From ec4f91e32b0feb146146a84fcbcd48430dd1aa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:30:46 +0100 Subject: [PATCH 1/7] fix: fix edge functions workers --- package-lock.json | 201 ++++++++++++++++-- packages/edge-functions/.gitignore | 3 +- packages/edge-functions/bootstrap-bundle.mjs | 15 ++ .../dev/deno/workers/config.mjs | 13 +- .../dev/deno/workers/runner.mjs | 28 ++- packages/edge-functions/dev/node/main.ts | 2 +- packages/edge-functions/package.json | 1 + packages/edge-functions/tsup.config.ts | 23 ++ 8 files changed, 256 insertions(+), 30 deletions(-) create mode 100644 packages/edge-functions/bootstrap-bundle.mjs diff --git a/package-lock.json b/package-lock.json index 1ddcb673..bd61efc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2936,6 +2936,12 @@ ], "peer": true }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -2943,6 +2949,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -8253,6 +8271,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8608,6 +8638,21 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -10909,6 +10954,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", @@ -10947,7 +11004,7 @@ "semver": "^7.5.3", "tmp-promise": "^3.0.3", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": "^14.16.0 || >=16.0.0" @@ -11047,7 +11104,7 @@ "@netlify/types": "2.0.2", "npm-run-all2": "^7.0.2", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": ">=20.6.1" @@ -11074,7 +11131,7 @@ "@netlify/api": "^14.0.3", "@netlify/types": "2.0.2", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": ">=20.6.1" @@ -11107,7 +11164,7 @@ "@types/write-file-atomic": "^4.0.3", "tmp-promise": "^3.0.3", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": "^18.14.0 || >=20" @@ -11231,13 +11288,129 @@ }, "devDependencies": { "@netlify/types": "2.0.2", + "execa": "^9.6.0", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": ">=18.0.0" } }, + "packages/edge-functions/node_modules/execa": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "packages/edge-functions/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/edge-functions/node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "packages/edge-functions/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/edge-functions/node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/edge-functions/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/edge-functions/node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/edge-functions/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/functions": { "name": "@netlify/functions", "version": "4.1.4", @@ -11263,7 +11436,7 @@ "semver": "^7.6.3", "tsd": "^0.32.0", "tsup": "^8.0.2", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": ">=18.0.0" @@ -11441,7 +11614,7 @@ "@netlify/dev-utils": "^3.2.0", "@types/node": "^20.17.57", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.1.4" }, "engines": { "node": ">=20.6.1" @@ -11470,7 +11643,7 @@ "devDependencies": { "@netlify/dev-utils": "^3.2.0", "tsup": "^8.5.0", - "vitest": "^3.2.2" + "vitest": "^3.1.4" }, "engines": { "node": ">=20.6.1" @@ -11490,7 +11663,7 @@ "devDependencies": { "npm-run-all2": "^7.0.2", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": "^18.14.0 || >=20.6.1" @@ -11593,7 +11766,7 @@ "@netlify/dev-utils": "3.2.0", "@types/jsonwebtoken": "9.0.9", "tsup": "^8.5.0", - "vitest": "^3.2.2" + "vitest": "^3.1.4" }, "engines": { "node": ">=20.6.1" @@ -11613,7 +11786,7 @@ "@netlify/dev-utils": "^3.2.0", "@types/node": "^20.17.57", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": ">=20.6.1" @@ -11626,7 +11799,7 @@ "devDependencies": { "@types/node": "^18.19.110", "tsup": "^8.0.0", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": "^18.14.0 || >=20" @@ -11669,7 +11842,7 @@ "@netlify/dev-utils": "^3.2.0", "@types/mime-types": "^2.1.4", "tsup": "^8.5.0", - "vitest": "^3.2.2" + "vitest": "^3.1.4" }, "engines": { "node": ">=20.6.1" @@ -11716,7 +11889,7 @@ "playwright": "^1.52.0", "tsup": "^8.0.0", "vite": "^6.3.4", - "vitest": "^3.2.2" + "vitest": "^3.0.0" }, "engines": { "node": "^20.6.1 || >=22" diff --git a/packages/edge-functions/.gitignore b/packages/edge-functions/.gitignore index 7b4a69ce..aa2750f1 100644 --- a/packages/edge-functions/.gitignore +++ b/packages/edge-functions/.gitignore @@ -1,2 +1,3 @@ dist -dist-dev \ No newline at end of file +dist-dev +dev/deno/bootstrap.mjs diff --git a/packages/edge-functions/bootstrap-bundle.mjs b/packages/edge-functions/bootstrap-bundle.mjs new file mode 100644 index 00000000..5039d1d6 --- /dev/null +++ b/packages/edge-functions/bootstrap-bundle.mjs @@ -0,0 +1,15 @@ +import * as esbuild from 'npm:esbuild' +import { denoPlugins } from 'jsr:@luca/esbuild-deno-loader@^0.11.1' + +const [entryPoint, outfile] = Deno.args + +await esbuild.build({ + bundle: true, + entryPoints: [entryPoint], + format: 'esm', + minify: true, + outfile, + plugins: denoPlugins(), +}) + +await esbuild.stop() diff --git a/packages/edge-functions/dev/deno/workers/config.mjs b/packages/edge-functions/dev/deno/workers/config.mjs index 1a75fb3a..eed100cd 100644 --- a/packages/edge-functions/dev/deno/workers/config.mjs +++ b/packages/edge-functions/dev/deno/workers/config.mjs @@ -1,12 +1,17 @@ // @ts-check +/// /** * @typedef {import('../../shared/types.ts').SerializedError} SerializedError - * @typedef {import('./types.js').ConfigResponseMessage} ConfigResponseMessage + * @typedef {import('./types.ts').ConfigResponseMessage} ConfigResponseMessage * @typedef {import('./types.ts').Message} Message */ -self.onmessage = async (e) => { +/** @type {DedicatedWorkerGlobalScope} */ +// @ts-ignore We are inside a worker, so the global scope is `DedicatedWorkerGlobalScope`. +const worker = globalThis + +worker.addEventListener('message', async (e) => { const message = /** @type {Message} */ (e.data) if (message.type === 'configRequest') { @@ -38,10 +43,10 @@ self.onmessage = async (e) => { await Promise.allSettled(imports) - self.postMessage(/** @type {ConfigResponseMessage} */ ({ type: 'configResponse', data: { configs, errors } })) + worker.postMessage(/** @type {ConfigResponseMessage} */ ({ type: 'configResponse', data: { configs, errors } })) return } throw new Error('Unsupported message') -} +}) diff --git a/packages/edge-functions/dev/deno/workers/runner.mjs b/packages/edge-functions/dev/deno/workers/runner.mjs index 4a3c6955..7f4c4738 100644 --- a/packages/edge-functions/dev/deno/workers/runner.mjs +++ b/packages/edge-functions/dev/deno/workers/runner.mjs @@ -1,21 +1,26 @@ // @ts-check +/// +import { handleRequest } from '../bootstrap.mjs' /** - * @typedef {import('./types.js').Message} Message - * @typedef {import('./types.js').RunResponseStartMessage} RunResponseStartMessage - * @typedef {import('./types.js').RunResponseChunkMessage} RunResponseChunkMessage - * @typedef {import('./types.js').RunResponseEndMessage} RunResponseEndMessage + * @typedef {import('./types.ts').Message} Message + * @typedef {import('./types.ts').RunResponseStartMessage} RunResponseStartMessage + * @typedef {import('./types.ts').RunResponseChunkMessage} RunResponseChunkMessage + * @typedef {import('./types.ts').RunResponseEndMessage} RunResponseEndMessage */ const consoleLog = globalThis.console.log /** @type {Map} */ const fetchRewrites = new Map() -self.onmessage = async (e) => { +/** @type {DedicatedWorkerGlobalScope} */ +// @ts-ignore We are inside a worker, so the global scope is `DedicatedWorkerGlobalScope`. +const worker = globalThis + +worker.addEventListener('message', async (e) => { const message = /** @type {Message} */ (e.data) if (message.type === 'request') { - const { handleRequest } = await import(message.data.bootstrapURL) const body = message.data.method === 'GET' || message.data.method === 'HEAD' ? undefined : message.data.body const req = new Request(message.data.url, { body, @@ -35,12 +40,14 @@ self.onmessage = async (e) => { await Promise.allSettled(imports) const res = await handleRequest(req, functions, { + // @ts-ignore TODO: Figure out why `fetchRewrites` is not being picked up + // as part of the type. fetchRewrites, rawLogger: consoleLog, requestTimeout: message.data.timeout, }) - self.postMessage( + worker.postMessage( /** @type {RunResponseStartMessage} */ ({ type: 'responseStart', data: { @@ -58,7 +65,8 @@ self.onmessage = async (e) => { break } - self.postMessage( + // @ts-expect-error TODO: Figure out type mismatch. + worker.postMessage( /** @type {RunResponseChunkMessage} */ ({ type: 'responseChunk', data: { chunk: value }, @@ -68,10 +76,10 @@ self.onmessage = async (e) => { } } - self.postMessage(/** @type {RunResponseEndMessage} */ ({ type: 'responseEnd' })) + worker.postMessage(/** @type {RunResponseEndMessage} */ ({ type: 'responseEnd' })) return } throw new Error('Unsupported message') -} +}) diff --git a/packages/edge-functions/dev/node/main.ts b/packages/edge-functions/dev/node/main.ts index 580b7d5f..6194ee0b 100644 --- a/packages/edge-functions/dev/node/main.ts +++ b/packages/edge-functions/dev/node/main.ts @@ -272,7 +272,7 @@ export class EdgeFunctionsHandler { versionRange: '^2.2.4', }) const runOptions: RunOptions = { - bootstrapURL: await getBootstrapURL(), + bootstrapURL: './bootstrap.mjs', denoPort, requestTimeout: this.requestTimeout, } diff --git a/packages/edge-functions/package.json b/packages/edge-functions/package.json index b830a693..0f10a46f 100644 --- a/packages/edge-functions/package.json +++ b/packages/edge-functions/package.json @@ -51,6 +51,7 @@ }, "devDependencies": { "@netlify/types": "2.0.2", + "execa": "^9.6.0", "tsup": "^8.0.0", "vitest": "^3.0.0" }, diff --git a/packages/edge-functions/tsup.config.ts b/packages/edge-functions/tsup.config.ts index 51cccdd2..a0d9f2c5 100644 --- a/packages/edge-functions/tsup.config.ts +++ b/packages/edge-functions/tsup.config.ts @@ -3,10 +3,14 @@ import path from 'node:path' import { fileURLToPath } from 'node:url' import { argv } from 'node:process' +import { getURL } from '@netlify/edge-functions-bootstrap/version' +import { execa } from 'execa' import { defineConfig } from 'tsup' const __filename = fileURLToPath(import.meta.url) +const BOOTSTRAP_FILENAME = 'bootstrap.mjs' + export default defineConfig([ { clean: true, @@ -45,10 +49,29 @@ export default defineConfig([ // preserve the original structure, so that the relative path to the worker // files is consistent. onSuccess: async () => { + const bootstrapURL = await getURL() const denoPath = path.resolve(path.dirname(__filename), 'dev', 'deno') const distPath = path.resolve(path.dirname(__filename), 'dist-dev') await fs.cp(denoPath, path.resolve(distPath, 'deno'), { recursive: true }) + + // We need to bundle the bootstrap layer with the package because Deno + // does not support HTTP imports when inside a `node_modukes` directory. + const distBootstrapPath = path.resolve(distPath, 'deno', BOOTSTRAP_FILENAME) + await execa( + 'deno', + ['run', '--allow-all', '--no-lock', 'bootstrap-bundle.mjs', bootstrapURL, distBootstrapPath], + { + stdio: 'inherit', + }, + ) + + // In addition to putting the bootstrap file in `dist-dev`, we must also + // put it in the source directory so that the reference to the bootstrap + // file still works in tests and local development. This is not great. At + // least we're gitignoring the file so that it doesn't end up in version + // control. + await fs.cp(distBootstrapPath, path.resolve(denoPath, BOOTSTRAP_FILENAME)) }, }, ]) From e57ebc53fc780bf6e7fcbd403df5b0d860a10fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:37:11 +0100 Subject: [PATCH 2/7] chore: downgrade execa --- package-lock.json | 2 +- packages/edge-functions/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 448c7a3b..e5712817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11288,7 +11288,7 @@ }, "devDependencies": { "@netlify/types": "2.0.2", - "execa": "^9.6.0", + "execa": "^8.0.1", "tsup": "^8.0.0", "vitest": "^3.0.0" }, diff --git a/packages/edge-functions/package.json b/packages/edge-functions/package.json index 0f10a46f..c60e476c 100644 --- a/packages/edge-functions/package.json +++ b/packages/edge-functions/package.json @@ -51,7 +51,7 @@ }, "devDependencies": { "@netlify/types": "2.0.2", - "execa": "^9.6.0", + "execa": "^8.0.1", "tsup": "^8.0.0", "vitest": "^3.0.0" }, From 5cb2ec7c617b4e890413e7525cef4ebe08667008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:38:57 +0100 Subject: [PATCH 3/7] chore: update lock file --- package-lock.json | 173 ---------------------------------------------- 1 file changed, 173 deletions(-) diff --git a/package-lock.json b/package-lock.json index e5712817..471318a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2936,12 +2936,6 @@ ], "peer": true }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "dev": true - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -2949,18 +2943,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -5642,7 +5624,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -8271,18 +8252,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8638,21 +8607,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-ms": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", - "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", - "dev": true, - "dependencies": { - "parse-ms": "^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -10954,18 +10908,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yoctocolors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", - "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", @@ -11296,121 +11238,6 @@ "node": ">=18.0.0" } }, - "packages/edge-functions/node_modules/execa": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", - "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", - "dev": true, - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.1", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.2.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/edge-functions/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/edge-functions/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "engines": { - "node": ">=18.18.0" - } - }, - "packages/edge-functions/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/edge-functions/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/edge-functions/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/edge-functions/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/edge-functions/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/functions": { "name": "@netlify/functions", "version": "4.1.4", From bf1274edff8d8bf7c8e7b2d0e433fd772ea38126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:42:10 +0100 Subject: [PATCH 4/7] chore: add Deno to CI steps --- .github/workflows/lint.yaml | 5 +++++ .github/workflows/publint.yaml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 8328bf44..f8b6a0ae 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -22,6 +22,11 @@ jobs: node-version: lts/* cache: 'npm' + - name: Setup Deno + uses: denoland/setup-deno@v1 + with: + deno-version: 2.2.4 + - name: Install dependencies run: npm ci --no-audit diff --git a/.github/workflows/publint.yaml b/.github/workflows/publint.yaml index 79e0d7e1..aca91ae1 100644 --- a/.github/workflows/publint.yaml +++ b/.github/workflows/publint.yaml @@ -22,6 +22,10 @@ jobs: with: node-version: lts/* cache: 'npm' + - name: Setup Deno + uses: denoland/setup-deno@v1 + with: + deno-version: 2.2.4 - name: Install dependencies run: npm ci - name: Build From d55a2a44b7f83e50a62b66951317913ed9477650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:44:57 +0100 Subject: [PATCH 5/7] chore: format --- .github/workflows/lint.yaml | 2 +- .github/workflows/publint.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index f8b6a0ae..792bc281 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -25,7 +25,7 @@ jobs: - name: Setup Deno uses: denoland/setup-deno@v1 with: - deno-version: 2.2.4 + deno-version: 2.2.4 - name: Install dependencies run: npm ci --no-audit diff --git a/.github/workflows/publint.yaml b/.github/workflows/publint.yaml index aca91ae1..86ee1001 100644 --- a/.github/workflows/publint.yaml +++ b/.github/workflows/publint.yaml @@ -25,7 +25,7 @@ jobs: - name: Setup Deno uses: denoland/setup-deno@v1 with: - deno-version: 2.2.4 + deno-version: 2.2.4 - name: Install dependencies run: npm ci - name: Build From 3e9ab615ca9ec81913c35e3560e96a21bcb9b24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 16:50:53 +0100 Subject: [PATCH 6/7] refactor: remote `bootstrapURL` param --- packages/edge-functions/dev/deno/invoke.mjs | 6 ++---- packages/edge-functions/dev/deno/server.mjs | 10 +++++----- packages/edge-functions/dev/deno/workers/types.ts | 1 - packages/edge-functions/dev/node/main.ts | 2 -- packages/edge-functions/dev/shared/types.ts | 1 - 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/edge-functions/dev/deno/invoke.mjs b/packages/edge-functions/dev/deno/invoke.mjs index 72d0bc96..a6ab3115 100644 --- a/packages/edge-functions/dev/deno/invoke.mjs +++ b/packages/edge-functions/dev/deno/invoke.mjs @@ -1,7 +1,7 @@ // @ts-check /** - * @typedef {import('./workers/types.js').Message} Message + * @typedef {import('./workers/types.ts').Message} Message */ /** @@ -10,11 +10,10 @@ * construct a `Response`. * * @param {Request} req - * @param {string} bootstrapURL * @param {Record} functions * @param {number} requestTimeout */ -export function invoke(req, bootstrapURL, functions, requestTimeout) { +export function invoke(req, functions, requestTimeout) { return new Promise((resolve, reject) => { const worker = new Worker(new URL('./workers/runner.mjs', import.meta.url).href, { type: 'module', @@ -43,7 +42,6 @@ export function invoke(req, bootstrapURL, functions, requestTimeout) { type: 'request', data: { body: await req.arrayBuffer(), - bootstrapURL, functions, headers: Object.fromEntries(req.headers.entries()), method: req.method, diff --git a/packages/edge-functions/dev/deno/server.mjs b/packages/edge-functions/dev/deno/server.mjs index cd935401..8c3868b7 100644 --- a/packages/edge-functions/dev/deno/server.mjs +++ b/packages/edge-functions/dev/deno/server.mjs @@ -15,7 +15,7 @@ import { invoke } from './invoke.mjs' * * @param {RunOptions} options */ -export const serveLocal = ({ bootstrapURL, denoPort: port, requestTimeout }) => { +export const serveLocal = ({ denoPort: port, requestTimeout }) => { const serveOptions = { // Adding a no-op listener to avoid the default one, which prints a message // we don't want. @@ -37,11 +37,11 @@ export const serveLocal = ({ bootstrapURL, denoPort: port, requestTimeout }) => // the Deno server take a list of functions, import them, and return their // configs. if (method === 'NETLIFYCONFIG') { + const functionsParam = url.searchParams.get('functions') + // This is the list of all the functions found in the project. /** @type {Record} */ - const availableFunctions = url.searchParams.has('functions') - ? JSON.parse(decodeURIComponent(url.searchParams.get('functions'))) - : {} + const availableFunctions = functionsParam ? JSON.parse(decodeURIComponent(functionsParam)) : {} functions = availableFunctions @@ -59,7 +59,7 @@ export const serveLocal = ({ bootstrapURL, denoPort: port, requestTimeout }) => } try { - return await invoke(request, bootstrapURL, functions, requestTimeout) + return await invoke(request, functions, requestTimeout) } catch (error) { return getErrorResponse(error) } diff --git a/packages/edge-functions/dev/deno/workers/types.ts b/packages/edge-functions/dev/deno/workers/types.ts index 1081663d..70e79ddd 100644 --- a/packages/edge-functions/dev/deno/workers/types.ts +++ b/packages/edge-functions/dev/deno/workers/types.ts @@ -31,7 +31,6 @@ export interface RunRequestMessage { type: 'request' data: { body: ArrayBuffer - bootstrapURL: string functions: Record headers: Record method: string diff --git a/packages/edge-functions/dev/node/main.ts b/packages/edge-functions/dev/node/main.ts index 6194ee0b..bf54293a 100644 --- a/packages/edge-functions/dev/node/main.ts +++ b/packages/edge-functions/dev/node/main.ts @@ -11,7 +11,6 @@ import { EdgeFunction, FunctionConfig, } from '@netlify/edge-bundler' -import { getURL as getBootstrapURL } from '@netlify/edge-functions-bootstrap/version' import { base64Encode } from '@netlify/runtime-utils' import getAvailablePort from 'get-port' @@ -272,7 +271,6 @@ export class EdgeFunctionsHandler { versionRange: '^2.2.4', }) const runOptions: RunOptions = { - bootstrapURL: './bootstrap.mjs', denoPort, requestTimeout: this.requestTimeout, } diff --git a/packages/edge-functions/dev/shared/types.ts b/packages/edge-functions/dev/shared/types.ts index e60c8847..47526010 100644 --- a/packages/edge-functions/dev/shared/types.ts +++ b/packages/edge-functions/dev/shared/types.ts @@ -1,5 +1,4 @@ export interface RunOptions { - bootstrapURL: string denoPort: number requestTimeout: number } From b5e14458867d490a48637cc06bf4b06f41bb8b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 6 Jun 2025 17:42:17 +0100 Subject: [PATCH 7/7] chore: lint-ignore file --- eslint.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index 79818a4b..a224fe7f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -30,7 +30,7 @@ export default tseslint.config( // TODO: Move this to `edge-functions` package. { - ignores: ['packages/**/deno'], + ignores: ['packages/**/deno', 'packages/edge-functions/bootstrap-bundle.mjs'], }, // JavaScript-specific rules