diff --git a/README.md b/README.md index 61339da..533b900 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ export default (req: MiddlewareRequest) => { This plugin uses Vercel's [Build Output API (v3)](https://vercel.com/docs/build-output-api/v3) which requires an Environment Variable named `ENABLE_VC_BUILD` to be set to `1` in order to enable the feature. +## Credits + +A lot of code are taken from Next.js since it's basically the same logic, all credits to Next.js authors. + ## Sponsors [![sponsors](https://sponsors-images.egoist.sh/sponsors.svg)](https://github.com/sponsors/egoist) diff --git a/example/middleware.ts b/example/middleware.ts index b5ef2a3..9d0c975 100644 --- a/example/middleware.ts +++ b/example/middleware.ts @@ -1,6 +1,10 @@ -import { MiddlewareRequest, MiddlewareResponse } from "vite-vercel/server" +import { + MiddlewareRequest, + MiddlewareResponse, + MiddlewareFetchEvent, +} from "vite-vercel/server" -export default (req: MiddlewareRequest) => { +export default (req: MiddlewareRequest, event: MiddlewareFetchEvent) => { const url = new URL(req.url) if (url.pathname === "/from-middleware") { @@ -13,5 +17,21 @@ export default (req: MiddlewareRequest) => { ) } + if (url.pathname === "/stream") { + const { readable, writable } = new TransformStream() + + event.waitUntil( + (async () => { + const writer = writable.getWriter() + const encoder = new TextEncoder() + writer.write(encoder.encode("Hello, world! Streamed!")) + writer.write(encoder.encode("response")) + writer.close() + })(), + ) + + return new Response(readable) + } + return MiddlewareResponse.next() } diff --git a/packages/vercel-utils/package.json b/packages/vercel-utils/package.json index bda60bb..91e8dba 100644 --- a/packages/vercel-utils/package.json +++ b/packages/vercel-utils/package.json @@ -20,10 +20,20 @@ "./server-node": { "import": "./dist/server-node.mjs", "default": "./dist/server-node.js" + }, + "./polyfills": { + "import": "./dist/polyfills.mjs", + "default": "./dist/polyfills.js" } }, "devDependencies": { + "next": "^12.1.6", "tsup": "5.12.6" }, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@web-std/file": "^3.0.2", + "node-fetch": "^3.2.4", + "web-streams-polyfill": "^3.2.1" + } } diff --git a/packages/vercel-utils/polyfills.d.ts b/packages/vercel-utils/polyfills.d.ts new file mode 100644 index 0000000..a5e87bb --- /dev/null +++ b/packages/vercel-utils/polyfills.d.ts @@ -0,0 +1 @@ +export * from "./dist/polyfills" diff --git a/packages/vite-vercel/src/server-prepare.ts b/packages/vercel-utils/src/polyfills.ts similarity index 58% rename from packages/vite-vercel/src/server-prepare.ts rename to packages/vercel-utils/src/polyfills.ts index 2bed816..7e889c4 100644 --- a/packages/vite-vercel/src/server-prepare.ts +++ b/packages/vercel-utils/src/polyfills.ts @@ -1,5 +1,9 @@ -import fetch, { Request, Response, Headers, FormData } from "node-fetch" +import "web-streams-polyfill/es2018" +import fetch, { FormData } from "node-fetch" import { Blob as NodeBlob, File as NodeFile } from "@web-std/file" +import { Response } from "next/dist/server/web/spec-compliant/response" +import { Request } from "next/dist/server/web/spec-compliant/request" +import { Headers } from "next/dist/server/web/spec-compliant/headers" globalThis.Request = globalThis.Request || Request globalThis.Response = globalThis.Response || Response diff --git a/packages/vercel-utils/src/server-node.ts b/packages/vercel-utils/src/server-node.ts index 5f03e1f..a02d9e7 100644 --- a/packages/vercel-utils/src/server-node.ts +++ b/packages/vercel-utils/src/server-node.ts @@ -1,5 +1,6 @@ import type { IncomingMessage } from "http" -import { MiddlewareRequest } from "./server" +import { Readable } from "stream" +import { MiddlewareFetchEvent, MiddlewareRequest } from "./server" /** * Create Web Headers from Node Headers @@ -42,3 +43,22 @@ export function createRequest(req: IncomingMessage): Request { return new MiddlewareRequest(url.href, init) } + +export function createFetchEvent(request: Request): MiddlewareFetchEvent { + return new MiddlewareFetchEvent(request) +} + +export function bodyStreamToNodeStream(bodyStream: ReadableStream): Readable { + const reader = bodyStream.getReader() + return Readable.from( + (async function* () { + while (true) { + const { done, value } = await reader.read() + if (done) { + return + } + yield value + } + })(), + ) +} diff --git a/packages/vercel-utils/src/server.ts b/packages/vercel-utils/src/server.ts index 039ccbf..a0804e9 100644 --- a/packages/vercel-utils/src/server.ts +++ b/packages/vercel-utils/src/server.ts @@ -1,51 +1,4 @@ -import { validateURL } from "./server-utils" - -const REDIRECTS = new Set([301, 302, 303, 307, 308]) - -export class MiddlewareRequest extends Request { - /** Only available on Vercel */ - geo?: { - city?: string - country?: string - region?: string - latitude?: string - longitude?: string - } - - /** Only available on Vercel */ - ip?: string -} - -export class MiddlewareResponse extends Response { - static rewrite(destination: string | URL) { - return new MiddlewareResponse(null, { - headers: { - "x-middleware-rewrite": validateURL(destination), - }, - }) - } - - static next() { - return new MiddlewareResponse(null, { - headers: { - "x-middleware-next": "1", - }, - }) - } - - static redirect(url: string | URL, status = 307) { - if (!REDIRECTS.has(status)) { - throw new RangeError( - 'Failed to execute "redirect" on "response": Invalid status code', - ) - } - - const destination = validateURL(url) - return new MiddlewareResponse(destination, { - headers: { Location: destination }, - status, - }) - } -} - +export { MiddlewareRequest } from "./spec-extensions/request" +export { MiddlewareResponse } from "./spec-extensions/response" +export { MiddlewareFetchEvent } from "./spec-extensions/fetch-event" export { isBot } from "./server-utils" diff --git a/packages/vercel-utils/src/spec-extensions/fetch-event.ts b/packages/vercel-utils/src/spec-extensions/fetch-event.ts new file mode 100644 index 0000000..222fd33 --- /dev/null +++ b/packages/vercel-utils/src/spec-extensions/fetch-event.ts @@ -0,0 +1,3 @@ +import { FetchEvent } from "next/dist/server/web/spec-compliant/fetch-event" + +export class MiddlewareFetchEvent extends FetchEvent {} diff --git a/packages/vercel-utils/src/spec-extensions/request.ts b/packages/vercel-utils/src/spec-extensions/request.ts new file mode 100644 index 0000000..486476b --- /dev/null +++ b/packages/vercel-utils/src/spec-extensions/request.ts @@ -0,0 +1,15 @@ +import { Request } from "next/dist/server/web/spec-compliant/request" + +export class MiddlewareRequest extends Request { + /** Only available on Vercel */ + geo?: { + city?: string + country?: string + region?: string + latitude?: string + longitude?: string + } + + /** Only available on Vercel */ + ip?: string +} diff --git a/packages/vercel-utils/src/spec-extensions/response.ts b/packages/vercel-utils/src/spec-extensions/response.ts new file mode 100644 index 0000000..2f0765a --- /dev/null +++ b/packages/vercel-utils/src/spec-extensions/response.ts @@ -0,0 +1,3 @@ +import { NextResponse } from "next/dist/server/web/spec-extension/response" + +export class MiddlewareResponse extends NextResponse {} diff --git a/packages/vite-vercel/package.json b/packages/vite-vercel/package.json index 4bd075e..94d1476 100644 --- a/packages/vite-vercel/package.json +++ b/packages/vite-vercel/package.json @@ -34,15 +34,14 @@ "@types/fs-extra": "^9.0.13", "@types/node": "^17.0.31", "prettier": "2.6.2", - "tsup": "5.12.6", + "tsup": "5.12.7", "typescript": "4.6.4", "vite": "^2.9.7", "vitest": "0.10.1" }, "dependencies": { - "@web-std/file": "^3.0.2", "fs-extra": "^10.1.0", - "node-fetch": "^3.2.4", + "resolve-from": "^5.0.0", "vercel-utils": "workspace:*" }, "peerDependencies": { diff --git a/packages/vite-vercel/src/plugin.ts b/packages/vite-vercel/src/plugin.ts index ce84ac4..0a0142d 100644 --- a/packages/vite-vercel/src/plugin.ts +++ b/packages/vite-vercel/src/plugin.ts @@ -1,11 +1,24 @@ import path from "path" import { type Plugin, build } from "vite" import fs from "fs-extra" +import resolveFrom from "resolve-from" +import { fileURLToPath } from "url" export type Options = { middleware?: string } +declare const TSUP_FORMAT: string + +const resolve = (id: string) => { + return resolveFrom( + TSUP_FORMAT === "esm" + ? path.dirname(fileURLToPath(import.meta.url)) + : __dirname, + id, + ) +} + const writeJson = (filepath: string, data: any) => { fs.mkdirSync(path.dirname(filepath), { recursive: true }) fs.writeFileSync(filepath, JSON.stringify(data)) @@ -16,7 +29,6 @@ export const plugin = (options: Options = {}): Plugin => { return { name: "vercel", - // @ts-expect-error config() { return { ssr: { @@ -28,6 +40,11 @@ export const plugin = (options: Options = {}): Plugin => { // No sure why sometimes this is externalized noExternal: [/vite-vercel/], }, + resolve: { + alias: { + "vercel-utils": path.dirname(resolve("vercel-utils/polyfills")), + }, + }, } }, @@ -44,9 +61,9 @@ export const plugin = (options: Options = {}): Plugin => { server.middlewares.use(async (req, res, next) => { if (serverNode) return next() - await server.ssrLoadModule(`/@id/vite-vercel/server-prepare`) + await server.ssrLoadModule("vercel-utils/polyfills") serverNode = (await server.ssrLoadModule( - `/@id/vite-vercel/server-node`, + "vercel-utils/server-node", )) as any next() }) @@ -57,7 +74,8 @@ export const plugin = (options: Options = {}): Plugin => { try { const middleware = await server.ssrLoadModule(`/@fs${middlewarePath}`) const request = serverNode.createRequest(req) - let response: Response = await middleware.default(request) + const event = serverNode.createFetchEvent(request) + let response: Response = await middleware.default(request, event) if (response.headers.get("x-middleware-next") === "1") { return next() @@ -74,8 +92,8 @@ export const plugin = (options: Options = {}): Plugin => { } }) - const ab = await response.arrayBuffer() - res.end(Buffer.from(ab)) + const stream = serverNode.bodyStreamToNodeStream(response.body!) + stream.pipe(res) } catch (error) { if (error instanceof Error) { server.ssrFixStacktrace(error) @@ -109,6 +127,7 @@ export const plugin = (options: Options = {}): Plugin => { preserveEntrySignatures: "strict", }, outDir: `.vercel/output/functions/main.func`, + target: "esnext", }, }) diff --git a/packages/vite-vercel/src/polyfills.ts b/packages/vite-vercel/src/polyfills.ts new file mode 100644 index 0000000..94379a6 --- /dev/null +++ b/packages/vite-vercel/src/polyfills.ts @@ -0,0 +1 @@ +import "vercel-utils/polyfills" diff --git a/packages/vite-vercel/src/server.ts b/packages/vite-vercel/src/server.ts index 094dde9..fb2723e 100644 --- a/packages/vite-vercel/src/server.ts +++ b/packages/vite-vercel/src/server.ts @@ -1 +1,5 @@ -export * from "vercel-utils/server" +export { + MiddlewareFetchEvent, + MiddlewareRequest, + MiddlewareResponse, +} from "vercel-utils/server" diff --git a/packages/vite-vercel/tsup.config.ts b/packages/vite-vercel/tsup.config.ts index d40d630..0f6271e 100644 --- a/packages/vite-vercel/tsup.config.ts +++ b/packages/vite-vercel/tsup.config.ts @@ -1,10 +1,14 @@ import { defineConfig } from "tsup" -export default defineConfig({ - target: "node14", - entry: ["./src/index.ts", "./src/server.ts", "./src/server-prepare.ts"], - format: ["esm", "cjs"], - dts: true, - splitting: true, - shims: false, +export default defineConfig(() => { + return { + target: "node14", + entry: ["./src/index.ts", "./src/server.ts", "./src/polyfills.ts"], + format: ["cjs", "esm"], + dts: true, + splitting: true, + shims: false, + minify: true, + sourcemap: true, + } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 384ded5..683211e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,8 +22,17 @@ importers: packages/vercel-utils: specifiers: + '@web-std/file': ^3.0.2 + next: ^12.1.6 + node-fetch: ^3.2.4 tsup: 5.12.6 + web-streams-polyfill: ^3.2.1 + dependencies: + '@web-std/file': 3.0.2 + node-fetch: 3.2.4 + web-streams-polyfill: 3.2.1 devDependencies: + next: 12.1.6 tsup: 5.12.6 packages/vite-vercel: @@ -31,26 +40,24 @@ importers: '@egoist/prettier-config': 1.0.0 '@types/fs-extra': ^9.0.13 '@types/node': ^17.0.31 - '@web-std/file': ^3.0.2 fs-extra: ^10.1.0 - node-fetch: ^3.2.4 prettier: 2.6.2 - tsup: 5.12.6 + resolve-from: ^5.0.0 + tsup: 5.12.7 typescript: 4.6.4 vercel-utils: workspace:* vite: ^2.9.7 vitest: 0.10.1 dependencies: - '@web-std/file': 3.0.2 fs-extra: 10.1.0 - node-fetch: 3.2.4 + resolve-from: 5.0.0 vercel-utils: link:../vercel-utils devDependencies: '@egoist/prettier-config': 1.0.0 '@types/fs-extra': 9.0.13 '@types/node': 17.0.31 prettier: 2.6.2 - tsup: 5.12.6_typescript@4.6.4 + tsup: 5.12.7_typescript@4.6.4 typescript: 4.6.4 vite: 2.9.7 vitest: 0.10.1 @@ -89,6 +96,118 @@ packages: type-detect: 4.0.8 dev: true + /@next/env/12.1.6: + resolution: {integrity: sha512-Te/OBDXFSodPU6jlXYPAXpmZr/AkG6DCATAxttQxqOWaq6eDFX25Db3dK0120GZrSZmv4QCe9KsZmJKDbWs4OA==} + dev: true + + /@next/swc-android-arm-eabi/12.1.6: + resolution: {integrity: sha512-BxBr3QAAAXWgk/K7EedvzxJr2dE014mghBSA9iOEAv0bMgF+MRq4PoASjuHi15M2zfowpcRG8XQhMFtxftCleQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@next/swc-android-arm64/12.1.6: + resolution: {integrity: sha512-EboEk3ROYY7U6WA2RrMt/cXXMokUTXXfnxe2+CU+DOahvbrO8QSWhlBl9I9ZbFzJx28AGB9Yo3oQHCvph/4Lew==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@next/swc-darwin-arm64/12.1.6: + resolution: {integrity: sha512-P0EXU12BMSdNj1F7vdkP/VrYDuCNwBExtRPDYawgSUakzi6qP0iKJpya2BuLvNzXx+XPU49GFuDC5X+SvY0mOw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@next/swc-darwin-x64/12.1.6: + resolution: {integrity: sha512-9FptMnbgHJK3dRDzfTpexs9S2hGpzOQxSQbe8omz6Pcl7rnEp9x4uSEKY51ho85JCjL4d0tDLBcXEJZKKLzxNg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@next/swc-linux-arm-gnueabihf/12.1.6: + resolution: {integrity: sha512-PvfEa1RR55dsik/IDkCKSFkk6ODNGJqPY3ysVUZqmnWMDSuqFtf7BPWHFa/53znpvVB5XaJ5Z1/6aR5CTIqxPw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@next/swc-linux-arm64-gnu/12.1.6: + resolution: {integrity: sha512-53QOvX1jBbC2ctnmWHyRhMajGq7QZfl974WYlwclXarVV418X7ed7o/EzGY+YVAEKzIVaAB9JFFWGXn8WWo0gQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@next/swc-linux-arm64-musl/12.1.6: + resolution: {integrity: sha512-CMWAkYqfGdQCS+uuMA1A2UhOfcUYeoqnTW7msLr2RyYAys15pD960hlDfq7QAi8BCAKk0sQ2rjsl0iqMyziohQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@next/swc-linux-x64-gnu/12.1.6: + resolution: {integrity: sha512-AC7jE4Fxpn0s3ujngClIDTiEM/CQiB2N2vkcyWWn6734AmGT03Duq6RYtPMymFobDdAtZGFZd5nR95WjPzbZAQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@next/swc-linux-x64-musl/12.1.6: + resolution: {integrity: sha512-c9Vjmi0EVk0Kou2qbrynskVarnFwfYIi+wKufR9Ad7/IKKuP6aEhOdZiIIdKsYWRtK2IWRF3h3YmdnEa2WLUag==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@next/swc-win32-arm64-msvc/12.1.6: + resolution: {integrity: sha512-3UTOL/5XZSKFelM7qN0it35o3Cegm6LsyuERR3/OoqEExyj3aCk7F025b54/707HTMAnjlvQK3DzLhPu/xxO4g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@next/swc-win32-ia32-msvc/12.1.6: + resolution: {integrity: sha512-8ZWoj6nCq6fI1yCzKq6oK0jE6Mxlz4MrEsRyu0TwDztWQWe7rh4XXGLAa2YVPatYcHhMcUL+fQQbqd1MsgaSDA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@next/swc-win32-x64-msvc/12.1.6: + resolution: {integrity: sha512-4ZEwiRuZEicXhXqmhw3+de8Z4EpOLQj/gp+D9fFWo6ii6W1kBkNNvvEx4A90ugppu+74pT1lIJnOuz3A9oQeJA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@nodelib/fs.scandir/2.1.4: resolution: {integrity: sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==} engines: {node: '>= 8'} @@ -271,6 +390,10 @@ packages: engines: {node: '>=6'} dev: true + /caniuse-lite/1.0.30001336: + resolution: {integrity: sha512-/YxSlBmL7iKXTbIJ48IQTnAOBk7XmWsxhBF1PZLOko5Dt9qc4Pl+84lfqG3Tc4EuavurRn1QLoVJGxY2iSycfw==} + dev: true + /chai/4.3.6: resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} engines: {node: '>=4'} @@ -1155,6 +1278,46 @@ packages: hasBin: true dev: true + /next/12.1.6: + resolution: {integrity: sha512-cebwKxL3/DhNKfg9tPZDQmbRKjueqykHHbgaoG4VBRH3AHQJ2HO0dbKFiS1hPhe1/qgc2d/hFeadsbPicmLD+A==} + engines: {node: '>=12.22.0'} + hasBin: true + peerDependencies: + fibers: '>= 3.1.0' + node-sass: ^6.0.0 || ^7.0.0 + react: ^17.0.2 || ^18.0.0-0 + react-dom: ^17.0.2 || ^18.0.0-0 + sass: ^1.3.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + dependencies: + '@next/env': 12.1.6 + caniuse-lite: 1.0.30001336 + postcss: 8.4.5 + styled-jsx: 5.0.2 + optionalDependencies: + '@next/swc-android-arm-eabi': 12.1.6 + '@next/swc-android-arm64': 12.1.6 + '@next/swc-darwin-arm64': 12.1.6 + '@next/swc-darwin-x64': 12.1.6 + '@next/swc-linux-arm-gnueabihf': 12.1.6 + '@next/swc-linux-arm64-gnu': 12.1.6 + '@next/swc-linux-arm64-musl': 12.1.6 + '@next/swc-linux-x64-gnu': 12.1.6 + '@next/swc-linux-x64-musl': 12.1.6 + '@next/swc-win32-arm64-msvc': 12.1.6 + '@next/swc-win32-ia32-msvc': 12.1.6 + '@next/swc-win32-x64-msvc': 12.1.6 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: true + /node-domexception/1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -1296,6 +1459,15 @@ packages: source-map-js: 1.0.2 dev: true + /postcss/8.4.5: + resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.3 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /prettier/2.6.2: resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} engines: {node: '>=10.13.0'} @@ -1329,7 +1501,6 @@ packages: /resolve-from/5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - dev: true /resolve/1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} @@ -1440,6 +1611,20 @@ packages: engines: {node: '>=6'} dev: true + /styled-jsx/5.0.2: + resolution: {integrity: sha512-LqPQrbBh3egD57NBcHET4qcgshPks+yblyhPlH2GY8oaDgKs8SK4C3dBh3oSJjgzJ3G5t1SYEZGHkP+QEpX9EQ==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dev: true + /sucrase/3.20.3: resolution: {integrity: sha512-azqwq0/Bs6RzLAdb4dXxsCgMtAaD2hzmUr4UhSfsxO46JFPAwMnnb441B/qsudZiS6Ylea3JXZe3Q497lsgXzQ==} engines: {node: '>=8'} @@ -1538,8 +1723,8 @@ packages: - supports-color dev: true - /tsup/5.12.6_typescript@4.6.4: - resolution: {integrity: sha512-tpePOgdMRKRgazF+ujq9k1Fo44PUFUJJjRLtxq87pQrYW/Ub/fu1GpFGLzdUF9qjJ4FX1ykhf2d9mWCNy+jAtg==} + /tsup/5.12.7_typescript@4.6.4: + resolution: {integrity: sha512-+OxYroGLByY0Fm8DLZaB4nVMlD59VsQoNXdhnO9wOG+cOsKXUwN3ER9gaKOjZJG26eKUXebmDme0Cy3emfRvOQ==} hasBin: true peerDependencies: typescript: ^4.1.0