From 7ac6f660fe9ea0df4ae2b2610db6073f394e3ff8 Mon Sep 17 00:00:00 2001 From: Rahul Sethi <5822355+RamIdeas@users.noreply.github.com> Date: Fri, 13 Oct 2023 12:54:25 +0100 Subject: [PATCH] Revert "Revert "startDevWorker - Milestone 1" (#4171)" This reverts commit 88f15f61cad2a69c07e26203cc84ddb2da42deb3. --- fixtures/dev-env/.gitignore | 1 + fixtures/dev-env/package.json | 25 + fixtures/dev-env/tests/index.test.ts | 552 +++++++++++++++ fixtures/dev-env/tests/tsconfig.json | 12 + .../tests/index.test.ts | 11 +- packages/wrangler/.eslintrc.js | 1 + packages/wrangler/e2e/tsconfig.json | 2 +- packages/wrangler/package.json | 2 +- packages/wrangler/scripts/bundle.ts | 63 +- .../src/__tests__/api-devregistry.test.ts | 48 +- packages/wrangler/src/__tests__/dev.test.tsx | 2 + packages/wrangler/src/__tests__/jest.setup.ts | 40 +- packages/wrangler/src/api/dev.ts | 18 +- packages/wrangler/src/api/index.ts | 1 + .../src/api/startDevWorker/BaseController.ts | 40 ++ .../api/startDevWorker/BundlerController.ts | 44 ++ .../api/startDevWorker/ConfigController.ts | 42 ++ .../wrangler/src/api/startDevWorker/DevEnv.ts | 148 ++++ .../startDevWorker/LocalRuntimeController.ts | 41 ++ .../api/startDevWorker/NotImplementedError.ts | 15 + .../src/api/startDevWorker/ProxyController.ts | 527 ++++++++++++++ .../startDevWorker/RemoteRuntimeController.ts | 41 ++ .../startDevWorker/bundle-allowed-paths.ts | 99 +++ .../src/api/startDevWorker/devtools.ts | 41 ++ .../wrangler/src/api/startDevWorker/events.ts | 138 ++++ .../wrangler/src/api/startDevWorker/index.ts | 12 + .../wrangler/src/api/startDevWorker/types.ts | 197 ++++++ .../wrangler/src/api/startDevWorker/utils.ts | 43 ++ packages/wrangler/src/cli.ts | 4 +- packages/wrangler/src/dev.tsx | 3 +- packages/wrangler/src/dev/dev.tsx | 119 +++- packages/wrangler/src/dev/inspect.ts | 659 +----------------- packages/wrangler/src/dev/local.tsx | 88 +-- packages/wrangler/src/dev/miniflare.ts | 43 +- packages/wrangler/src/dev/remote.tsx | 77 +- packages/wrangler/src/dev/start-server.ts | 114 ++- packages/wrangler/src/dev/use-esbuild.ts | 6 + packages/wrangler/src/https-options.ts | 14 +- packages/wrangler/src/worker.d.ts | 4 + .../startDevWorker/InspectorProxyWorker.ts | 526 ++++++++++++++ .../templates/startDevWorker/ProxyWorker.ts | 260 +++++++ pnpm-lock.yaml | 133 +++- 42 files changed, 3430 insertions(+), 826 deletions(-) create mode 100644 fixtures/dev-env/.gitignore create mode 100644 fixtures/dev-env/package.json create mode 100644 fixtures/dev-env/tests/index.test.ts create mode 100644 fixtures/dev-env/tests/tsconfig.json create mode 100644 packages/wrangler/src/api/startDevWorker/BaseController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/BundlerController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/ConfigController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/DevEnv.ts create mode 100644 packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/NotImplementedError.ts create mode 100644 packages/wrangler/src/api/startDevWorker/ProxyController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/RemoteRuntimeController.ts create mode 100644 packages/wrangler/src/api/startDevWorker/bundle-allowed-paths.ts create mode 100644 packages/wrangler/src/api/startDevWorker/devtools.ts create mode 100644 packages/wrangler/src/api/startDevWorker/events.ts create mode 100644 packages/wrangler/src/api/startDevWorker/index.ts create mode 100644 packages/wrangler/src/api/startDevWorker/types.ts create mode 100644 packages/wrangler/src/api/startDevWorker/utils.ts create mode 100644 packages/wrangler/src/worker.d.ts create mode 100644 packages/wrangler/templates/startDevWorker/InspectorProxyWorker.ts create mode 100644 packages/wrangler/templates/startDevWorker/ProxyWorker.ts diff --git a/fixtures/dev-env/.gitignore b/fixtures/dev-env/.gitignore new file mode 100644 index 000000000000..1521c8b7652b --- /dev/null +++ b/fixtures/dev-env/.gitignore @@ -0,0 +1 @@ +dist diff --git a/fixtures/dev-env/package.json b/fixtures/dev-env/package.json new file mode 100644 index 000000000000..5502c9d0e0b8 --- /dev/null +++ b/fixtures/dev-env/package.json @@ -0,0 +1,25 @@ +{ + "name": "dev-env", + "version": "1.0.1", + "private": true, + "description": "", + "license": "ISC", + "author": "", + "main": "src/index.js", + "scripts": { + "test": "npx vitest run", + "test:ci": "npx vitest run", + "test:watch": "npx vitest", + "type:tests": "tsc -p ./tests/tsconfig.json" + }, + "devDependencies": { + "@types/ws": "^8.5.7", + "@cloudflare/workers-tsconfig": "workspace:^", + "get-port": "^7.0.0", + "miniflare": "3.20231002.1", + "undici": "^5.23.0", + "wrangler": "workspace:*", + "ws": "^8.14.2" + }, + "dependencies": {} +} diff --git a/fixtures/dev-env/tests/index.test.ts b/fixtures/dev-env/tests/index.test.ts new file mode 100644 index 000000000000..83e7baa04b83 --- /dev/null +++ b/fixtures/dev-env/tests/index.test.ts @@ -0,0 +1,552 @@ +import assert from "node:assert"; +import getPort from "get-port"; +import { + Miniflare, + type Response as MiniflareResponse, + type MiniflareOptions, + Log, +} from "miniflare"; +import * as undici from "undici"; +import { WebSocket } from "ws"; +import { beforeEach, afterEach, describe, test, expect, vi } from "vitest"; +import { unstable_DevEnv as DevEnv } from "wrangler"; +import type { ProxyData } from "wrangler/src/api"; +import type { StartDevWorkerOptions } from "wrangler/src/api/startDevWorker/types"; +import type { EsbuildBundle } from "wrangler/src/dev/use-esbuild"; + +const fakeBundle = {} as EsbuildBundle; + +let devEnv: DevEnv; +let mf: Miniflare | undefined; +let res: MiniflareResponse | undici.Response | undefined; +let ws: WebSocket | undefined; + +type OptionalKeys = Omit & Partial>; + +beforeEach(() => { + devEnv = new DevEnv(); + mf = undefined; + res = undefined; + ws = undefined; +}); +afterEach(async () => { + await devEnv?.teardown(); + await mf?.dispose(); + await ws?.close(); + + vi.resetAllMocks(); +}); + +async function fakeStartUserWorker(options: { + script: string; + name?: string; + mfOpts?: Partial; + config?: OptionalKeys; +}) { + const config: StartDevWorkerOptions = { + ...options.config, + name: options.name ?? "test-worker", + script: { contents: options.script }, + }; + const mfOpts: MiniflareOptions = Object.assign( + { + port: 0, + inspectorPort: 0, + modules: true, + compatibilityDate: "2023-08-01", + name: config.name, + script: options.script, + log: Object.assign(new Log(), { error() {} }), // TODO: remove when this bug is fixed https://jira.cfdata.org/browse/DEVX-983 + }, + options.mfOpts + ); + + assert("script" in mfOpts); + + fakeConfigUpdate(config); + fakeReloadStart(config); + + const worker = devEnv.startWorker(config); + const { proxyWorker, inspectorProxyWorker } = await devEnv.proxy.ready + .promise; + const proxyWorkerUrl = await proxyWorker.ready; + const inspectorProxyWorkerUrl = await inspectorProxyWorker.ready; + + mf = new Miniflare(mfOpts); + + const userWorkerUrl = await mf.ready; + const userWorkerInspectorUrl = await mf.getInspectorURL(); + fakeReloadComplete(config, mfOpts, userWorkerUrl, userWorkerInspectorUrl); + + return { + worker, + mf, + mfOpts, + config, + userWorkerUrl, + userWorkerInspectorUrl, + proxyWorkerUrl, + inspectorProxyWorkerUrl, + }; +} + +async function fakeUserWorkerChanges({ + script, + mfOpts, + config, +}: { + script?: string; + mfOpts: MiniflareOptions; + config: StartDevWorkerOptions; +}) { + assert(mf); + assert("script" in mfOpts); + + config = { + ...config, + script: { + ...config.script, + ...(script ? { contents: script } : undefined), + }, + }; + mfOpts = { + ...mfOpts, + script: script ?? mfOpts.script, + }; + + fakeReloadStart(config); + + await mf.setOptions(mfOpts); + + const userWorkerUrl = await mf.ready; + const userWorkerInspectorUrl = await mf.getInspectorURL(); + fakeReloadComplete( + config, + mfOpts, + userWorkerUrl, + userWorkerInspectorUrl, + 1000 + ); + + return { mfOpts, config, mf, userWorkerUrl, userWorkerInspectorUrl }; +} + +function fireAndForgetFakeUserWorkerChanges( + ...args: Parameters +) { + // fire and forget the reload -- this let's us test request buffering + void fakeUserWorkerChanges(...args); +} + +function fakeConfigUpdate(config: StartDevWorkerOptions) { + devEnv.proxy.onConfigUpdate({ + type: "configUpdate", + config, + }); + + return config; // convenience to allow calling and defining new config inline but also store the new object +} +function fakeReloadStart(config: StartDevWorkerOptions) { + devEnv.proxy.onReloadStart({ + type: "reloadStart", + config, + bundle: fakeBundle, + }); + + return config; +} +function fakeReloadComplete( + config: StartDevWorkerOptions, + mfOpts: MiniflareOptions, + userWorkerUrl: URL, + userWorkerInspectorUrl: URL, + delay = 100 +) { + const proxyData: ProxyData = { + userWorkerUrl: { + protocol: userWorkerUrl.protocol, + hostname: userWorkerUrl.hostname, + port: userWorkerUrl.port, + }, + userWorkerInspectorUrl: { + protocol: userWorkerInspectorUrl.protocol, + hostname: userWorkerInspectorUrl.hostname, + port: userWorkerInspectorUrl.port, + pathname: `/core:user:${config.name}`, + }, + userWorkerInnerUrlOverrides: { + protocol: config?.dev?.urlOverrides?.secure ? "https:" : "http:", + hostname: config?.dev?.urlOverrides?.hostname, + }, + headers: {}, + liveReload: config.dev?.liveReload, + }; + + setTimeout(() => { + devEnv.proxy.onReloadComplete({ + type: "reloadComplete", + config, + bundle: fakeBundle, + proxyData, + }); + }, delay); + + return { config, mfOpts }; // convenience to allow calling and defining new config/mfOpts inline but also store the new objects +} + +describe("startDevWorker: ProxyController", () => { + test("ProxyWorker buffers requests while runtime reloads", async () => { + const run = await fakeStartUserWorker({ + script: ` + export default { + fetch() { + return new Response("body:1"); + } + } + `, + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:1"); + + fireAndForgetFakeUserWorkerChanges({ + mfOpts: run.mfOpts, + config: run.config, + script: run.mfOpts.script.replace("1", "2"), + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:2"); + }); + + test("InspectorProxyWorker discovery endpoints + devtools websocket connection", async () => { + const run = await fakeStartUserWorker({ + script: ` + export default { + fetch() { + console.log('Inside mock user worker'); + + return new Response("body:1"); + } + } + `, + }); + + await devEnv.proxy.ready; + res = await undici.fetch(`http://${run.inspectorProxyWorkerUrl.host}/json`); + + await expect(res.json()).resolves.toBeInstanceOf(Array); + + ws = new WebSocket( + `ws://${run.inspectorProxyWorkerUrl.host}/core:user:${run.config.name}` + ); + const openPromise = new Promise((resolve) => { + ws?.addEventListener("open", resolve); + }); + const consoleAPICalledPromise = new Promise((resolve) => { + ws?.addEventListener("message", (event) => { + assert(typeof event.data === "string"); + if (event.data.includes("Runtime.consoleAPICalled")) { + resolve(JSON.parse(event.data)); + } + }); + }); + const executionContextCreatedPromise = new Promise((resolve) => { + ws?.addEventListener("message", (event) => { + assert(typeof event.data === "string"); + if (event.data.includes("Runtime.executionContextCreated")) { + resolve(JSON.parse(event.data)); + } + }); + }); + + await openPromise; + await run.worker.fetch("http://localhost"); + + await expect(consoleAPICalledPromise).resolves.toMatchObject({ + method: "Runtime.consoleAPICalled", + params: { + args: expect.arrayContaining([ + { type: "string", value: "Inside mock user worker" }, + ]), + }, + }); + await expect(executionContextCreatedPromise).resolves.toMatchObject({ + method: "Runtime.executionContextCreated", + params: { + context: { id: expect.any(Number) }, + }, + }); + }); + + test("User worker exception", async () => { + const consoleErrorSpy = vi.spyOn(console, "error"); + + const run = await fakeStartUserWorker({ + script: ` + export default { + fetch() { + throw new Error('Boom!'); + + return new Response("body:1"); + } + } + `, + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("Error: Boom!"); + + await new Promise((r) => setTimeout(r, 100)); // allow some time for the error to be logged (TODO: replace with retry/waitUntil helper) + expect(consoleErrorSpy).toBeCalledWith( + expect.stringContaining("Error: Boom!") + ); + + // test changes causing a new error cause the new error to propogate + fireAndForgetFakeUserWorkerChanges({ + script: ` + export default { + fetch() { + throw new Error('Boom 2!'); + + return new Response("body:2"); + } + } + `, + mfOpts: run.mfOpts, + config: run.config, + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("Error: Boom 2!"); + + await new Promise((r) => setTimeout(r, 100)); // allow some time for the error to be logged (TODO: replace with retry/waitUntil helper) + expect(consoleErrorSpy).toBeCalledWith( + expect.stringContaining("Error: Boom 2!") + ); + + // test eyeball requests receive the pretty error page + fireAndForgetFakeUserWorkerChanges({ + script: ` + export default { + fetch() { + const e = new Error('Boom 3!'); + + // this is how errors are serialised after they are caught by wrangler/miniflare3 middlewares + const error = { name: e.name, message: e.message, stack: e.stack }; + return Response.json(error, { + status: 500, + headers: { "MF-Experimental-Error-Stack": "true" }, + }); + } + } + `, + mfOpts: run.mfOpts, + config: run.config, + }); + + const proxyWorkerUrl = await devEnv.proxy.proxyWorker?.ready; + assert(proxyWorkerUrl); + res = await undici.fetch(proxyWorkerUrl, { + headers: { Accept: "text/html" }, + }); + await expect(res.text()).resolves.toEqual( + expect.stringContaining(`

Boom 3!

`) // pretty error page html snippet + ); + + // test further changes that fix the code + fireAndForgetFakeUserWorkerChanges({ + script: ` + export default { + fetch() { + return new Response("body:3"); + } + } + `, + mfOpts: run.mfOpts, + config: run.config, + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:3"); + + consoleErrorSpy.mockReset(); + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:3"); + + await new Promise((r) => setTimeout(r, 100)); // allow some time for the error to be logged (TODO: replace with retry/waitUntil helper) + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + + test("config.dev.{server,inspector} changes, restart the server instance", async () => { + const run = await fakeStartUserWorker({ + script: ` + export default { + fetch() { + return new Response("body:1"); + } + } + `, + config: { + dev: { + server: { port: await getPort() }, + inspector: { port: await getPort() }, + }, + }, + }); + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:1"); + + const oldPort = run.config.dev?.server?.port; + res = await undici.fetch(`http://127.0.0.1:${oldPort}`); + await expect(res.text()).resolves.toBe("body:1"); + + const config2 = fakeConfigUpdate({ + ...run.config, + dev: { + server: { port: await getPort() }, + inspector: { port: await getPort() }, + }, + }); + fakeReloadStart(config2); + fakeReloadComplete( + config2, + run.mfOpts, + run.userWorkerUrl, + run.userWorkerInspectorUrl + ); + + const newPort = config2.dev?.server?.port; + + res = await run.worker.fetch("http://dummy"); + await expect(res.text()).resolves.toBe("body:1"); + + res = await undici.fetch(`http://127.0.0.1:${newPort}`); + await expect(res.text()).resolves.toBe("body:1"); + + await expect( + undici.fetch(`http://127.0.0.1:${oldPort}`).then((r) => r.text()) + ).rejects.toMatchInlineSnapshot("[TypeError: fetch failed]"); + }); + + test("liveReload", async () => { + let resText: string; + const scriptRegex = / + `, + { html: true } + ); + } + }, + }); + + return htmlRewriter.transform(response); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 127df3302f4a..38cd17645c18 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,6 +102,30 @@ importers: specifier: workspace:* version: link:../../packages/wrangler + fixtures/dev-env: + devDependencies: + '@cloudflare/workers-tsconfig': + specifier: workspace:^ + version: link:../../packages/workers-tsconfig + '@types/ws': + specifier: ^8.5.7 + version: 8.5.7 + get-port: + specifier: ^7.0.0 + version: 7.0.0 + miniflare: + specifier: 3.20231002.1 + version: 3.20231002.1 + undici: + specifier: ^5.23.0 + version: 5.23.0 + wrangler: + specifier: workspace:* + version: link:../../packages/wrangler + ws: + specifier: ^8.14.2 + version: 8.14.2 + fixtures/external-durable-objects-app: devDependencies: '@cloudflare/workers-tsconfig': @@ -3479,6 +3503,15 @@ packages: marked: 0.3.19 dev: false + /@cloudflare/workerd-darwin-64@1.20231002.0: + resolution: {integrity: sha512-sgtjzVO/wtI/6S7O0bk4zQAv2xlvqOxB18AXzlit6uXgbYFGeQedRHjhKVMOacGmWEnM4C3ir/fxJGsc3Pyxng==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-darwin-64@1.20231016.0: resolution: {integrity: sha512-rPAnF8Q25+eHEsAopihWeftPW/P0QapY9d7qaUmtOXztWdd6YPQ7JuiWVj4Nvjphge1BleehxAbo4I3Z4L2H1g==} engines: {node: '>=16'} @@ -3487,6 +3520,15 @@ packages: requiresBuild: true optional: true + /@cloudflare/workerd-darwin-arm64@1.20231002.0: + resolution: {integrity: sha512-dv8nztYFaTYYgBpyy80vc4hdMYv9mhyNbvBsZywm8S7ivcIpzogi0UKkGU4E/G0lYK6W3WtwTBqwRe+pXJ1+Ww==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-darwin-arm64@1.20231016.0: resolution: {integrity: sha512-MvydDdiLXt+jy57vrVZ2lU6EQwCdpieyZoN8uBXSWzfG3zR/6dxU1+okvPQPlHN0jtlufqPeHrpJyAqqgLHUKA==} engines: {node: '>=16'} @@ -3495,6 +3537,15 @@ packages: requiresBuild: true optional: true + /@cloudflare/workerd-linux-64@1.20231002.0: + resolution: {integrity: sha512-UG8SlLcGzaQDSSw6FR4+Zf408925wkLOCAi8w5qEoFYu3g4Ef7ZenstesCOsyWL7qBDKx0/iwk6+a76W5IHI0Q==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-linux-64@1.20231016.0: resolution: {integrity: sha512-y6Sj37yTzM8QbAghG9LRqoSBrsREnQz8NkcmpjSxeK6KMc2g0L5A/OemCdugNlIiv+zRv9BYX1aosaoxY5JbeQ==} engines: {node: '>=16'} @@ -3503,6 +3554,15 @@ packages: requiresBuild: true optional: true + /@cloudflare/workerd-linux-arm64@1.20231002.0: + resolution: {integrity: sha512-GPaa66ZSq1gK09r87c5CJbHIApcIU//LVHz3rnUxK0//00YCwUuGUUK1dn/ylg+fVqDQxIDmH+ABnobBanvcDA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-linux-arm64@1.20231016.0: resolution: {integrity: sha512-LqMIRUHD1YeRg2TPIfIQEhapSKMFSq561RypvJoXZvTwSbaROxGdW6Ku+PvButqTkEvuAtfzN/kGje7fvfQMHg==} engines: {node: '>=16'} @@ -3511,6 +3571,15 @@ packages: requiresBuild: true optional: true + /@cloudflare/workerd-windows-64@1.20231002.0: + resolution: {integrity: sha512-ybIy+sCme0VO0RscndXvqWNBaRMUOc8vhi+1N2h/KDsKfNLsfEQph+XWecfKzJseUy1yE2rV1xei3BaNmaa6vg==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-windows-64@1.20231016.0: resolution: {integrity: sha512-96ojBwIHyiUAbsWlzBqo9P/cvH8xUh8SuBboFXtwAeXcJ6/urwKN2AqPa/QzOGUTCdsurWYiieARHT5WWWPhKw==} engines: {node: '>=16'} @@ -6035,6 +6104,12 @@ packages: '@types/node': 20.1.7 dev: true + /@types/ws@8.5.7: + resolution: {integrity: sha512-6UrLjiDUvn40CMrAubXuIVtj2PEfKDffJS7ychvnPU44j+KVeXmdHHTgqcM/dxLUTHxlXHiFM8Skmb8ozGdTnQ==} + dependencies: + '@types/node': 20.1.7 + dev: true + /@types/yargs-parser@20.2.1: resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==} dev: true @@ -6901,14 +6976,6 @@ packages: dependencies: acorn: 8.10.0 - /acorn-jsx@5.3.2(acorn@8.8.2): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.8.2 - dev: true - /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} @@ -9647,8 +9714,8 @@ packages: resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.8.2 - acorn-jsx: 5.3.2(acorn@8.8.2) + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.1 dev: true @@ -10377,6 +10444,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /get-port@7.0.0: + resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + engines: {node: '>=16'} + dev: true + /get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} dependencies: @@ -13176,6 +13248,28 @@ packages: engines: {node: '>=4'} dev: false + /miniflare@3.20231002.1: + resolution: {integrity: sha512-4xJ8FezJkQqHzCm71lovb9L/wJ0VV/odMFf5CIxfLTunsx97kTIlZnhS6aHuvcbzdztbWp1RR71K/1qFUHdpdQ==} + engines: {node: '>=16.13'} + dependencies: + acorn: 8.10.0 + acorn-walk: 8.2.0 + capnp-ts: 0.7.0(supports-color@9.2.2) + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + source-map-support: 0.5.21 + stoppable: 1.1.0 + undici: 5.23.0 + workerd: 1.20231002.0 + ws: 8.14.2 + youch: 3.2.3 + zod: 3.22.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /miniflare@3.20231016.0(supports-color@9.2.2): resolution: {integrity: sha512-AmlqI89zsnBJfC+nKKZdCB/fuu0q/br24Kqt9NZwcT6yJEpO5NytNKfjl6nJROHROwuJSRQR1T3yopCtG1/0DA==} engines: {node: '>=16.13'} @@ -13189,7 +13283,7 @@ packages: stoppable: 1.1.0 undici: 5.23.0 workerd: 1.20231016.0 - ws: 8.13.0 + ws: 8.14.2 youch: 3.2.3 zod: 3.22.2 transitivePeerDependencies: @@ -17537,6 +17631,19 @@ packages: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: true + /workerd@1.20231002.0: + resolution: {integrity: sha512-NFuUQBj30ZguDoPZ6bL40hINiu8aP2Pvxr/3xAdhWOwVFLuObPOiSdQ8qm4JYZ7jovxWjWE4Z7VR2avjIzEksQ==} + engines: {node: '>=16'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20231002.0 + '@cloudflare/workerd-darwin-arm64': 1.20231002.0 + '@cloudflare/workerd-linux-64': 1.20231002.0 + '@cloudflare/workerd-linux-arm64': 1.20231002.0 + '@cloudflare/workerd-windows-64': 1.20231002.0 + dev: true + /workerd@1.20231016.0: resolution: {integrity: sha512-v2GDb5XitSqgub/xm7EWHVAlAK4snxQu3itdMQxXstGtUG9hl79fQbXS/8fNFbmms2R2bAxUwSv47q8k5T5Erw==} engines: {node: '>=16'} @@ -17619,8 +17726,8 @@ packages: optional: true dev: true - /ws@8.13.0: - resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + /ws@8.14.2: + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1