diff --git a/.changeset/c3-frameworks-update-7179.md b/.changeset/c3-frameworks-update-7179.md deleted file mode 100644 index 1af2a3fd3f05..000000000000 --- a/.changeset/c3-frameworks-update-7179.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"create-cloudflare": patch ---- - -chore: update dependencies of "create-cloudflare" package - -The following dependency versions have been updated: - -| Dependency | From | To | -| ----------------- | ----- | ----- | -| create-docusaurus | 3.5.2 | 3.6.0 | diff --git a/.changeset/c3-frameworks-update-7188.md b/.changeset/c3-frameworks-update-7188.md deleted file mode 100644 index e6328b8896b2..000000000000 --- a/.changeset/c3-frameworks-update-7188.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"create-cloudflare": patch ---- - -chore: update dependencies of "create-cloudflare" package - -The following dependency versions have been updated: - -| Dependency | From | To | -| ---------- | ------ | ------ | -| gatsby | 5.13.7 | 5.14.0 | diff --git a/.changeset/clean-tigers-breathe.md b/.changeset/clean-tigers-breathe.md new file mode 100644 index 000000000000..19b38f12d662 --- /dev/null +++ b/.changeset/clean-tigers-breathe.md @@ -0,0 +1,5 @@ +--- +"wrangler": patch +--- + +Avoid an unnecessary GET request during `wrangler deploy`. diff --git a/.changeset/dependabot-update-7187.md b/.changeset/dependabot-update-7187.md deleted file mode 100644 index 79a4ac0092ac..000000000000 --- a/.changeset/dependabot-update-7187.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"miniflare": patch ---- - -chore: update dependencies of "miniflare" package - -The following dependency versions have been updated: - -| Dependency | From | To | -| ------------------------- | ------------- | ------------- | -| workerd | 1.20241022.0 | 1.20241106.1 | -| @cloudflare/workers-types | ^4.20241022.0 | ^4.20241106.0 | diff --git a/.changeset/famous-birds-remain.md b/.changeset/famous-birds-remain.md deleted file mode 100644 index a165a0647134..000000000000 --- a/.changeset/famous-birds-remain.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@cloudflare/wrangler-devtools": minor ---- - -feat: update devtools patches for release - -- rebases patches on top of latest devtools head -- removes CPU profiling tab -- adds performance tab diff --git a/.changeset/famous-keys-walk.md b/.changeset/famous-keys-walk.md deleted file mode 100644 index 22481a44d6a8..000000000000 --- a/.changeset/famous-keys-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"wrangler": patch ---- - -Ensure `workerd` processes are cleaned up after address-in-use errors diff --git a/.changeset/happy-items-buy.md b/.changeset/happy-items-buy.md deleted file mode 100644 index 755f1f479a2f..000000000000 --- a/.changeset/happy-items-buy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"create-cloudflare": patch ---- - -Rename the framework name - -The name currently displayed in the CLI is `Svelte`. However, all of the options actually create a `SvelteKit` app, and the name `SvelteKit` is also used in the [documentation](https://developers.cloudflare.com/pages/framework-guides/deploy-a-svelte-site/). diff --git a/.changeset/large-otters-search.md b/.changeset/large-otters-search.md deleted file mode 100644 index 1222f96e18e2..000000000000 --- a/.changeset/large-otters-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"wrangler": patch ---- - -Clarify dev registry messaging around locally connected services. The connection status of local service bindings & durable object bindings is now indicated by `connected` or `not connected` next to their entry in the bindings summary. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development diff --git a/.changeset/new-adults-float.md b/.changeset/new-adults-float.md new file mode 100644 index 000000000000..9a1b9cae2c11 --- /dev/null +++ b/.changeset/new-adults-float.md @@ -0,0 +1,5 @@ +--- +"wrangler": patch +--- + +fix console output for `wrangler d1 migrations create` diff --git a/.changeset/nice-chefs-hang.md b/.changeset/nice-chefs-hang.md new file mode 100644 index 000000000000..bc8d3523dad3 --- /dev/null +++ b/.changeset/nice-chefs-hang.md @@ -0,0 +1,7 @@ +--- +"wrangler": minor +--- + +feat: Tail Consumers are now supported for Workers with assets. + +You can now configure `tail_consumers` in conjunction with `assets` in your `wrangler.toml` file. Read more about [Static Assets](https://developers.cloudflare.com/workers/static-assets/) and [Tail Consumers](https://developers.cloudflare.com/workers/observability/logs/tail-workers/) in the documentation. diff --git a/.changeset/seven-parents-report.md b/.changeset/seven-parents-report.md deleted file mode 100644 index ccfce217a3e0..000000000000 --- a/.changeset/seven-parents-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@cloudflare/workers-shared": minor ---- - -Fixes bug where indexId was never set for router-worker and asset-worker diff --git a/.changeset/stale-phones-bathe.md b/.changeset/stale-phones-bathe.md new file mode 100644 index 000000000000..adc094c00948 --- /dev/null +++ b/.changeset/stale-phones-bathe.md @@ -0,0 +1,5 @@ +--- +"wrangler": patch +--- + +chore: upgrade chokidar to v4 diff --git a/.changeset/tame-bobcats-suffer.md b/.changeset/tame-bobcats-suffer.md new file mode 100644 index 000000000000..e0705ebad8bd --- /dev/null +++ b/.changeset/tame-bobcats-suffer.md @@ -0,0 +1,5 @@ +--- +"wrangler": minor +--- + +Added r2 bucket info command to Wrangler. Improved formatting of r2 bucket list output diff --git a/.changeset/thin-hairs-explain.md b/.changeset/thin-hairs-explain.md deleted file mode 100644 index 8a76fed555b4..000000000000 --- a/.changeset/thin-hairs-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"wrangler": minor ---- - -Added the ability to enable, disable, and get r2.dev public access URLs for R2 buckets. diff --git a/.changeset/young-lions-type.md b/.changeset/young-lions-type.md deleted file mode 100644 index 0319a0357084..000000000000 --- a/.changeset/young-lions-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-cloudflare": minor ---- - -feat: update experimental remix template to be based on its worker template diff --git a/.github/actions/run-c3-e2e/action.yml b/.github/actions/run-c3-e2e/action.yml index c17cf79f86ca..c7e3cca8b32a 100644 --- a/.github/actions/run-c3-e2e/action.yml +++ b/.github/actions/run-c3-e2e/action.yml @@ -54,11 +54,12 @@ runs: CI_OS: ${{ runner.os }} - name: Upload Logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: - name: e2e-logs${{inputs.experimental && '-experimental' || ''}}-${{matrix.os}} + name: e2e-logs${{inputs.quarantine && '-quarantine' || ''}}${{inputs.experimental && '-experimental' || ''}}-${{runner.os}}-${{inputs.packageManager}} path: packages/create-cloudflare/.e2e-logs${{inputs.experimental && '-experimental' || ''}} + include-hidden-files: true - name: Fail if errors detected shell: bash diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 05752938c467..9de0e9a05b95 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,6 +4,10 @@ _Describe your change..._ --- + + - Tests - [ ] TODO (before merge) - [ ] Tests included diff --git a/.github/workflows/c3-e2e-dependabot.yml b/.github/workflows/c3-e2e-dependabot.yml deleted file mode 100644 index eb093457bfc7..000000000000 --- a/.github/workflows/c3-e2e-dependabot.yml +++ /dev/null @@ -1,80 +0,0 @@ -# Runs the C3 e2e tests on dependabot PRs - -name: C3 E2E Tests (Dependabot) - -on: - pull_request: - paths: - - .changeset/c3-frameworks-update-*.md - -env: - bun-version: 1.0.3 - -jobs: - get-dependabot-bumped-framework: - name: "Get bumped framework (dependabot-only)" - runs-on: ubuntu-latest - outputs: - bumped-framework-cli: ${{ steps.detect.outputs.result }} - if: | - github.event.pull_request.user.login == 'dependabot[bot]' - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: detect-bumped-framework - id: detect - uses: actions/github-script@v7 - with: - result-encoding: string - script: | - const getBumpedFrameworkCli = require('.github/get-c3-dependabot-bumped-framework.cjs'); - return getBumpedFrameworkCli(); - - # For dependabot versioning PRs we only want to run the e2es for the specifically bumped - # framework (this is both for optimization and in order to reduce unnecessary flakiness) - e2e-only-dependabot-bumped-framework: - # Note: please keep this job in sync with the e2e one - #  in .github/workflows/c3-e2e.yml - needs: [get-dependabot-bumped-framework] - name: ${{ format('Run tests for {0}@{1} on {2}', matrix.pm.name, matrix.pm.version, matrix.os) }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - pm: - [ - { name: npm, version: "0.0.0" }, - { name: pnpm, version: "9.12.0" }, - { name: bun, version: "1.0.3" }, - { name: yarn, version: "1.0.0" }, - ] - # include a single windows test with pnpm - include: - - os: windows-latest - pm: { name: pnpm, version: "9.12.0" } - runs-on: ${{ matrix.os }} - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install Dependencies - uses: ./.github/actions/install-dependencies - with: - turbo-api: ${{ secrets.TURBO_API }} - turbo-team: ${{ secrets.TURBO_TEAM }} - turbo-token: ${{ secrets.TURBO_TOKEN }} - turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - - - name: E2E Tests - uses: ./.github/actions/run-c3-e2e - with: - packageManager: ${{ matrix.pm.name }} - packageManagerVersion: ${{ matrix.pm.version }} - framework: ${{ needs.get-dependabot-bumped-framework.outputs.bumped-framework-cli }} - accountId: ${{ secrets.C3_TEST_CLOUDFLARE_ACCOUNT_ID }} - apiToken: ${{ secrets.C3_TEST_CLOUDFLARE_API_TOKEN }} diff --git a/.github/workflows/c3-e2e-experimental.yml b/.github/workflows/c3-e2e-experimental.yml index 800cd82c919e..8505dcb2622f 100644 --- a/.github/workflows/c3-e2e-experimental.yml +++ b/.github/workflows/c3-e2e-experimental.yml @@ -3,8 +3,6 @@ name: C3 E2E Tests (experimental) on: pull_request: - paths: - - packages/create-cloudflare/** jobs: e2e: @@ -15,7 +13,6 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.pm.name }}-${{ matrix.pm.version }} cancel-in-progress: true name: ${{ format('Run experimental tests for {0}@{1} on {2}', matrix.pm.name, matrix.pm.version, matrix.os) }} - if: github.event.pull_request.head.repo.owner.login == 'cloudflare' && github.event.pull_request.user.login != 'dependabot[bot]' strategy: fail-fast: false matrix: diff --git a/.github/workflows/c3-e2e.yml b/.github/workflows/c3-e2e.yml index 3c3ef3c3fa71..77892ea2352b 100644 --- a/.github/workflows/c3-e2e.yml +++ b/.github/workflows/c3-e2e.yml @@ -3,8 +3,6 @@ name: C3 E2E Tests on: pull_request: - paths: - - packages/create-cloudflare/** jobs: e2e: @@ -15,7 +13,6 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.pm.name }}-${{ matrix.pm.version }} cancel-in-progress: true name: ${{ format('Run tests for {0}@{1} on {2}', matrix.pm.name, matrix.pm.version, matrix.os) }} - if: github.event.pull_request.head.repo.owner.login == 'cloudflare' && github.event.pull_request.user.login != 'dependabot[bot]' strategy: fail-fast: false matrix: diff --git a/.github/workflows/deploy-pages-previews.yml b/.github/workflows/deploy-pages-previews.yml index 1fc6bf0e4c4b..98a83b9c6654 100644 --- a/.github/workflows/deploy-pages-previews.yml +++ b/.github/workflows/deploy-pages-previews.yml @@ -79,11 +79,34 @@ jobs: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} VITE_DEVTOOLS_PREVIEW_URL: ${{ env.VITE_DEVTOOLS_PREVIEW_URL }} + - name: "Comment on PR with Devtools Link" + if: contains(github.event.*.labels.*.name, 'preview:wrangler-devtools') + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: ${{ steps.finder.outputs.pr }} + message: | + The Wrangler DevTools preview is now live. You can access it directly at: ${{ env.VITE_DEVTOOLS_PREVIEW_URL }}/js_app + + In order to test the DevTools preview in `wrangler`: + + 1. `npx wrangler dev`. + 2. Hit `d` to open the DevTools in a fresh browser window. + 3. Paste the DevTools preview URL into the address bar (keeping all existing query parameters), e.g: + + ``` + - https://devtools.devprod.cloudflare.dev/js_app?theme=systemPreferred&ws=127.0.0.1%3A9229%2Fws&domain=tester&debugger=true + + https://8afc7d3d.cloudflare-devtools.pages.dev/js_app?theme=systemPreferred&ws=127.0.0.1%3A9229%2Fws&domain=tester&debugger=true + ``` + - name: "Comment on PR with Workers Playground Link" if: contains(github.event.*.labels.*.name, 'preview:wrangler-devtools') && contains(github.event.*.labels.*.name, 'preview:workers-playground') uses: marocchino/sticky-pull-request-comment@v2 with: - number: ${{ steps.finder.outputs.pr }} + header: ${{ steps.finder.outputs.pr }} + append: true message: | - The Wrangler DevTools and Workers Playground previews are now live. The Playground preview embeds the DevTools preview, so you can see them working together at: + + --- + + The Workers Playground preview is also now live. The Playground preview embeds the above DevTools preview, so you can see them working together at: ${{ env.PLAYGROUND_URL }}/playground diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index 45ff9e8b1476..56f3aeb1233f 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -2,7 +2,7 @@ name: Add issues to DevProd project on: issues: - types: [opened, labeled, unlabeled, transferred] + types: [opened, transferred] jobs: add-to-project: diff --git a/fixtures/additional-modules/package.json b/fixtures/additional-modules/package.json index 4c27717e80c0..2d6c2acd1816 100644 --- a/fixtures/additional-modules/package.json +++ b/fixtures/additional-modules/package.json @@ -5,7 +5,7 @@ "build": "wrangler deploy --dry-run --outdir=dist", "check:type": "tsc", "deploy": "wrangler deploy", - "start": "wrangler dev --x-dev-env", + "start": "wrangler dev", "test:ci": "vitest run", "test:watch": "vitest", "type:tests": "tsc -p ./test/tsconfig.json" diff --git a/fixtures/d1-worker-app/package.json b/fixtures/d1-worker-app/package.json index ff3f28d55fb2..82f305d91984 100644 --- a/fixtures/d1-worker-app/package.json +++ b/fixtures/d1-worker-app/package.json @@ -9,7 +9,7 @@ "db:query": "wrangler d1 execute UPDATE_THIS_FOR_REMOTE_USE --local --command='SELECT * FROM Customers'", "db:query-json": "wrangler d1 execute UPDATE_THIS_FOR_REMOTE_USE --local --command='SELECT * FROM Customers' --json", "db:reset": "wrangler d1 execute UPDATE_THIS_FOR_REMOTE_USE --local --file=./schema.sql", - "start": "wrangler dev --x-dev-env --local" + "start": "wrangler dev --local" }, "devDependencies": { "wrangler": "workspace:*" diff --git a/fixtures/interactive-dev-tests/tests/index.test.ts b/fixtures/interactive-dev-tests/tests/index.test.ts index 8bcce7877ba6..e32829e7b4fb 100644 --- a/fixtures/interactive-dev-tests/tests/index.test.ts +++ b/fixtures/interactive-dev-tests/tests/index.test.ts @@ -197,8 +197,7 @@ function getStartedWorkerdProcesses(): Process[] { } const devScripts = [ - { args: ["dev", "--x-dev-env"], expectedBody: "body" }, - { args: ["dev", "--no-x-dev-env"], expectedBody: "body" }, + { args: ["dev"], expectedBody: "body" }, { args: ["pages", "dev", "public"], expectedBody: "

body

" }, ]; const exitKeys = [ @@ -234,7 +233,7 @@ it.runIf(RUN_IF && nodePtySupported)( "hotkeys should be unregistered when the initial build fails", async () => { const wrangler = await startWranglerDev( - ["dev", "--x-dev-env", "src/startup-error.ts"], + ["dev", "src/startup-error.ts"], true ); diff --git a/fixtures/no-bundle-import/package.json b/fixtures/no-bundle-import/package.json index d419b7ae3239..ca8cb4800364 100644 --- a/fixtures/no-bundle-import/package.json +++ b/fixtures/no-bundle-import/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "deploy": "wrangler deploy", - "start": "wrangler dev --x-dev-env", + "start": "wrangler dev", "test:ci": "vitest run", "test:watch": "vitest" }, diff --git a/fixtures/nodejs-als-app/package.json b/fixtures/nodejs-als-app/package.json index 956529bff146..d8cd36660bb2 100644 --- a/fixtures/nodejs-als-app/package.json +++ b/fixtures/nodejs-als-app/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "build": "wrangler deploy --dry-run --outdir=./dist", - "dev": "wrangler dev --x-dev-env", + "dev": "wrangler dev", "test:ci": "vitest run", "test:watch": "vitest" }, diff --git a/fixtures/nodejs-hybrid-app/package.json b/fixtures/nodejs-hybrid-app/package.json index 32e180aa495e..298bd79064be 100644 --- a/fixtures/nodejs-hybrid-app/package.json +++ b/fixtures/nodejs-hybrid-app/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "build": "wrangler deploy --dry-run --outdir=./dist", - "dev": "wrangler dev --x-dev-env", + "dev": "wrangler dev", "test:ci": "vitest run", "test:watch": "vitest" }, diff --git a/fixtures/service-bindings-app/a/index.ts b/fixtures/service-bindings-app/a/index.ts deleted file mode 100644 index f15e6ad90cef..000000000000 --- a/fixtures/service-bindings-app/a/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default >{ - fetch(req, env) { - const url = new URL(req.url); - if (url.pathname === "/constructor") { - return new Response(env.BEE.constructor.name); - } - return env.BEE.fetch(req); - }, -}; diff --git a/fixtures/service-bindings-app/a/wrangler.toml b/fixtures/service-bindings-app/a/wrangler.toml deleted file mode 100644 index 0de9b2484706..000000000000 --- a/fixtures/service-bindings-app/a/wrangler.toml +++ /dev/null @@ -1,6 +0,0 @@ -name = 'a' -main = 'index.ts' - -[[services]] -binding = "BEE" -service = 'b' diff --git a/fixtures/service-bindings-app/b/index.ts b/fixtures/service-bindings-app/b/index.ts deleted file mode 100644 index e480c735753f..000000000000 --- a/fixtures/service-bindings-app/b/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - fetch() { - return new Response("hello world"); - }, -}; diff --git a/fixtures/service-bindings-app/b/wrangler.toml b/fixtures/service-bindings-app/b/wrangler.toml deleted file mode 100644 index 5d1081def676..000000000000 --- a/fixtures/service-bindings-app/b/wrangler.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = 'b' -main = 'index.ts' diff --git a/fixtures/service-bindings-app/package.json b/fixtures/service-bindings-app/package.json deleted file mode 100644 index 34815496cfad..000000000000 --- a/fixtures/service-bindings-app/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "service-bindings-app", - "private": true, - "description": "A test for service bindings", - "scripts": { - "check:type": "tsc", - "dev": "concurrently -s first -k \"wrangler dev --x-dev-env a/index.ts --port=8300 --inspector-port=0\" \"wrangler dev --x-dev-env b/index.ts --port=8301 --inspector-port=0\"", - "test:ci": "vitest run", - "test:watch": "vitest", - "type:tests": "tsc -p ./tests/tsconfig.json" - }, - "devDependencies": { - "@cloudflare/workers-tsconfig": "workspace:*", - "concurrently": "^8.2.2", - "undici": "catalog:default", - "wrangler": "workspace:*" - }, - "volta": { - "extends": "../../package.json" - } -} diff --git a/fixtures/service-bindings-app/tests/index.test.ts b/fixtures/service-bindings-app/tests/index.test.ts deleted file mode 100644 index 6ba0a0ac6c03..000000000000 --- a/fixtures/service-bindings-app/tests/index.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import path from "node:path"; -import { setTimeout } from "node:timers/promises"; -import { afterAll, beforeAll, describe, expect, it } from "vitest"; -import { unstable_dev, UnstableDevWorker } from "wrangler"; - -describe("Service Bindings", () => { - let aWorker: UnstableDevWorker; - - let bWorker: UnstableDevWorker; - - beforeAll(async () => { - bWorker = await unstable_dev(path.join(__dirname, "../b/index.ts"), { - config: path.join(__dirname, "../b/wrangler.toml"), - experimental: { - fileBasedRegistry: true, - disableExperimentalWarning: true, - devEnv: true, - }, - }); - await setTimeout(1000); - aWorker = await unstable_dev(path.join(__dirname, "../a/index.ts"), { - config: path.join(__dirname, "../a/wrangler.toml"), - experimental: { - fileBasedRegistry: true, - disableExperimentalWarning: true, - devEnv: true, - }, - }); - await setTimeout(1000); - }); - - it("connects up Durable Objects and keeps state across wrangler instances", async () => { - const responseA = await aWorker.fetch(`https://example.com/`); - const textA = await responseA.text(); - expect(textA).toEqual("hello world"); - - const responseB = await bWorker.fetch(`/`); - const textB = await responseB.text(); - expect(textB).toEqual("hello world"); - }); - - it("gives facade service workers a constructor name of Fetcher", async () => { - const responseA = await aWorker.fetch(`/constructor`); - const textA = await responseA.text(); - expect(textA).toEqual("Fetcher"); - }); - afterAll(async () => { - await aWorker?.stop(); - await bWorker?.stop(); - }); -}); diff --git a/fixtures/service-bindings-app/tests/tsconfig.json b/fixtures/service-bindings-app/tests/tsconfig.json deleted file mode 100644 index d2ce7f144694..000000000000 --- a/fixtures/service-bindings-app/tests/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@cloudflare/workers-tsconfig/tsconfig.json", - "compilerOptions": { - "types": ["node"] - }, - "include": ["**/*.ts", "../../../node-types.d.ts"] -} diff --git a/fixtures/service-bindings-app/tsconfig.json b/fixtures/service-bindings-app/tsconfig.json deleted file mode 100644 index 856398634a5e..000000000000 --- a/fixtures/service-bindings-app/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "CommonJS", - "lib": ["ES2020"], - "types": ["@cloudflare/workers-types"], - "moduleResolution": "node", - "noEmit": true, - "skipLibCheck": true - }, - "include": ["**/*.ts"], - "exclude": ["tests"] -} diff --git a/fixtures/service-bindings-app/vitest.config.mts b/fixtures/service-bindings-app/vitest.config.mts deleted file mode 100644 index 846cddc41995..000000000000 --- a/fixtures/service-bindings-app/vitest.config.mts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineProject, mergeConfig } from "vitest/config"; -import configShared from "../../vitest.shared"; - -export default mergeConfig( - configShared, - defineProject({ - test: {}, - }) -); diff --git a/fixtures/shared/src/run-wrangler-long-lived.ts b/fixtures/shared/src/run-wrangler-long-lived.ts index 84aff612e327..b16460b41a7e 100644 --- a/fixtures/shared/src/run-wrangler-long-lived.ts +++ b/fixtures/shared/src/run-wrangler-long-lived.ts @@ -29,7 +29,6 @@ export async function runWranglerPagesDev( "pages", "dev", publicPath, - "--x-dev-env", "--x-registry", "--ip=127.0.0.1", ...options, @@ -39,14 +38,7 @@ export async function runWranglerPagesDev( ); } else { return runLongLivedWrangler( - [ - "pages", - "dev", - "--x-dev-env", - "--x-registry", - "--ip=127.0.0.1", - ...options, - ], + ["pages", "dev", "--x-registry", "--ip=127.0.0.1", ...options], cwd, env ); @@ -67,7 +59,7 @@ export async function runWranglerDev( env?: NodeJS.ProcessEnv ) { return runLongLivedWrangler( - ["dev", "--x-dev-env", "--x-registry", "--ip=127.0.0.1", ...options], + ["dev", "--x-registry", "--ip=127.0.0.1", ...options], cwd, env ); diff --git a/fixtures/worker-ts/package.json b/fixtures/worker-ts/package.json index e8858a7ac44f..567b7d248278 100644 --- a/fixtures/worker-ts/package.json +++ b/fixtures/worker-ts/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "deploy": "wrangler deploy", - "start": "wrangler dev --x-dev-env" + "start": "wrangler dev" }, "devDependencies": { "@cloudflare/workers-types": "^4.20241106.0", diff --git a/fixtures/workflow/package.json b/fixtures/workflow/package.json index 2f8c45a42ab6..0c8fc04befd8 100644 --- a/fixtures/workflow/package.json +++ b/fixtures/workflow/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "deploy": "wrangler deploy", - "start": "wrangler dev --x-dev-env", + "start": "wrangler dev", "test:ci": "vitest" }, "devDependencies": { diff --git a/package.json b/package.json index c87668a88487..0e571cee2881 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "@types/node": "$@types/node" }, "patchedDependencies": { - "ink@3.2.0": "patches/ink@3.2.0.patch", "@cloudflare/component-listbox@1.10.6": "patches/@cloudflare__component-listbox@1.10.6.patch", "capnp-ts@0.7.0": "patches/capnp-ts@0.7.0.patch", "pg@8.11.3": "patches/pg@8.11.3.patch", diff --git a/packages/create-cloudflare/CHANGELOG.md b/packages/create-cloudflare/CHANGELOG.md index eada06c69bc4..17036fa4e0ba 100644 --- a/packages/create-cloudflare/CHANGELOG.md +++ b/packages/create-cloudflare/CHANGELOG.md @@ -1,5 +1,63 @@ # create-cloudflare +## 2.32.1 + +### Patch Changes + +- [#7217](https://github.com/cloudflare/workers-sdk/pull/7217) [`f76da8d`](https://github.com/cloudflare/workers-sdk/commit/f76da8d61f0d4fa02c3de132363b95699c0a80c9) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "create-cloudflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ----------------- | ----- | ----- | + | create-docusaurus | 3.6.0 | 3.6.1 | + +- [#7218](https://github.com/cloudflare/workers-sdk/pull/7218) [`39675b5`](https://github.com/cloudflare/workers-sdk/commit/39675b517c9f8ad35023137ca3f52fe486e25107) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "create-cloudflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ------------ | ------ | ------ | + | create-remix | 2.13.1 | 2.14.0 | + +- [#7219](https://github.com/cloudflare/workers-sdk/pull/7219) [`287a5d0`](https://github.com/cloudflare/workers-sdk/commit/287a5d0e4d73fd1fc4e17aed5596436dbca1aae0) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "create-cloudflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------ | ------ | + | create-vue | 3.12.0 | 3.12.1 | + +- [#6569](https://github.com/cloudflare/workers-sdk/pull/6569) [`7be8f76`](https://github.com/cloudflare/workers-sdk/commit/7be8f763967d0f50a2cced0520db8f7a7b691fe4) Thanks [@penalosa](https://github.com/penalosa)! - Make sure `wrangler deploy` and `wrangler pages deploy` are run in an interactive context in C3, so that users are able to respond to interactive prompts + +## 2.32.0 + +### Minor Changes + +- [#7170](https://github.com/cloudflare/workers-sdk/pull/7170) [`f292294`](https://github.com/cloudflare/workers-sdk/commit/f292294ba2e545742d8801f2f3060763547b7ccb) Thanks [@edmundhung](https://github.com/edmundhung)! - feat: update experimental remix template to be based on its worker template + +### Patch Changes + +- [#7179](https://github.com/cloudflare/workers-sdk/pull/7179) [`a4f5647`](https://github.com/cloudflare/workers-sdk/commit/a4f5647a368c3d6857fa425bee2827493eda2dd1) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "create-cloudflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ----------------- | ----- | ----- | + | create-docusaurus | 3.5.2 | 3.6.0 | + +- [#7188](https://github.com/cloudflare/workers-sdk/pull/7188) [`28edf9b`](https://github.com/cloudflare/workers-sdk/commit/28edf9b2eb08a978e016bc1d320459f33d5590b8) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "create-cloudflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------ | ------ | + | gatsby | 5.13.7 | 5.14.0 | + +- [#7109](https://github.com/cloudflare/workers-sdk/pull/7109) [`492533f`](https://github.com/cloudflare/workers-sdk/commit/492533f19e4840b8f93d9e29c0c267ce742f2fc5) Thanks [@jsparkdev](https://github.com/jsparkdev)! - Rename the framework name + + The name currently displayed in the CLI is `Svelte`. However, all of the options actually create a `SvelteKit` app, and the name `SvelteKit` is also used in the [documentation](https://developers.cloudflare.com/pages/framework-guides/deploy-a-svelte-site/). + ## 2.31.2 ### Patch Changes diff --git a/packages/create-cloudflare/package.json b/packages/create-cloudflare/package.json index 8335d138e0fe..d20a0327d8d9 100644 --- a/packages/create-cloudflare/package.json +++ b/packages/create-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudflare", - "version": "2.31.2", + "version": "2.32.1", "description": "A CLI for creating and deploying new applications to Cloudflare.", "keywords": [ "cloudflare", diff --git a/packages/create-cloudflare/src/__tests__/deploy.test.ts b/packages/create-cloudflare/src/__tests__/deploy.test.ts index a4a8f6e9ce39..8da1ad0d80d5 100644 --- a/packages/create-cloudflare/src/__tests__/deploy.test.ts +++ b/packages/create-cloudflare/src/__tests__/deploy.test.ts @@ -130,8 +130,10 @@ describe("deploy helpers", async () => { ctx.template.platform = "pages"; ctx.commitMessage = commitMsg; mockInsideGitRepo(false); - vi.mocked(runCommand).mockResolvedValueOnce(deployedUrl); - + vi.mocked(runCommand).mockResolvedValueOnce(""); + vi.mocked(readFile).mockImplementationOnce( + () => `{"type":"deploy", "targets":["${deployedUrl}"]}`, + ); await runDeploy(ctx); expect(runCommand).toHaveBeenCalledWith( ["npm", "run", "deploy", "--", "--commit-message", `"${commitMsg}"`], diff --git a/packages/create-cloudflare/src/deploy.ts b/packages/create-cloudflare/src/deploy.ts index 7f9eea53d217..3fd7d7ea08bd 100644 --- a/packages/create-cloudflare/src/deploy.ts +++ b/packages/create-cloudflare/src/deploy.ts @@ -1,9 +1,13 @@ +import { mkdtemp } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { startSection, updateStatus } from "@cloudflare/cli"; import { blue, brandColor, dim } from "@cloudflare/cli/colors"; import TOML from "@iarna/toml"; import { processArgument } from "helpers/args"; import { C3_DEFAULTS, openInBrowser } from "helpers/cli"; import { quoteShellArgs, runCommand } from "helpers/command"; +import { readFile } from "helpers/files"; import { detectPackageManager } from "helpers/packageManagers"; import { poll } from "helpers/poll"; import { isInsideGitRepo } from "./git"; @@ -99,12 +103,17 @@ export const runDeploy = async (ctx: C3Context) => { : []), ]; - const result = await runCommand(deployCmd, { - silent: true, + const outputFile = join( + await mkdtemp(join(tmpdir(), "c3-wrangler-deploy-")), + "output.json", + ); + + await runCommand(deployCmd, { cwd: ctx.project.path, env: { CLOUDFLARE_ACCOUNT_ID: ctx.account.id, NODE_ENV: "production", + WRANGLER_OUTPUT_FILE_PATH: outputFile, }, startText: "Deploying your application", doneText: `${brandColor("deployed")} ${dim( @@ -112,11 +121,24 @@ export const runDeploy = async (ctx: C3Context) => { )}`, }); - const deployedUrlRegex = /https:\/\/.+\.(pages|workers)\.dev/; - const deployedUrlMatch = result.match(deployedUrlRegex); - if (deployedUrlMatch) { - ctx.deployment.url = deployedUrlMatch[0]; - } else { + try { + const contents = readFile(outputFile); + + const entries = contents + .split("\n") + .filter(Boolean) + .map((entry) => JSON.parse(entry)); + const url: string | undefined = + entries.find((entry) => entry.type === "deploy")?.targets?.[0] ?? + entries.find((entry) => entry.type === "pages-deploy")?.url; + const deployedUrlRegex = /https:\/\/.+\.(pages|workers)\.dev/; + const deployedUrlMatch = url?.match(deployedUrlRegex); + if (deployedUrlMatch) { + ctx.deployment.url = deployedUrlMatch[0]; + } else { + throw new Error("Failed to find deployment url."); + } + } catch { throw new Error("Failed to find deployment url."); } diff --git a/packages/create-cloudflare/src/frameworks/package.json b/packages/create-cloudflare/src/frameworks/package.json index 5df2f6cd7dec..69297af822f8 100644 --- a/packages/create-cloudflare/src/frameworks/package.json +++ b/packages/create-cloudflare/src/frameworks/package.json @@ -8,14 +8,14 @@ "create-astro": "4.10.0", "create-analog": "1.8.1", "@angular/create": "18.2.11", - "create-docusaurus": "3.6.0", + "create-docusaurus": "3.6.1", "create-hono": "0.14.2", "create-next-app": "14.2.5", "create-qwik": "1.9.1", "create-vite": "5.5.5", - "create-remix": "2.13.1", + "create-remix": "2.14.0", "create-solid": "0.5.13", - "create-vue": "3.12.0", + "create-vue": "3.12.1", "gatsby": "5.14.0", "nuxi": "3.15.0", "sv": "0.6.1" diff --git a/packages/create-cloudflare/turbo.json b/packages/create-cloudflare/turbo.json index b25e84ec1a10..4788d8353d22 100644 --- a/packages/create-cloudflare/turbo.json +++ b/packages/create-cloudflare/turbo.json @@ -26,7 +26,8 @@ "E2E_EXPERIMENTAL", "TEST_PM" ], - "dependsOn": ["build"] + "dependsOn": ["build"], + "outputs": [".e2e-logs", ".e2e-logs-experimental"] } } } diff --git a/packages/devprod-status-bot/src/index.ts b/packages/devprod-status-bot/src/index.ts index 9bf2c6b7ea72..83ced8192455 100644 --- a/packages/devprod-status-bot/src/index.ts +++ b/packages/devprod-status-bot/src/index.ts @@ -189,7 +189,6 @@ async function sendStartThreadMessage(pat: string, webhookUrl: string, ai: Ai) { pr.user && [ "penalosa", - "RamIdeas", "lrapoport-cf", "petebacondarwin", "CarmenPopoviciu", diff --git a/packages/miniflare/CHANGELOG.md b/packages/miniflare/CHANGELOG.md index bdb3e47b648a..7843e7c2e17f 100644 --- a/packages/miniflare/CHANGELOG.md +++ b/packages/miniflare/CHANGELOG.md @@ -1,5 +1,18 @@ # miniflare +## 3.20241106.0 + +### Patch Changes + +- [#7187](https://github.com/cloudflare/workers-sdk/pull/7187) [`1db7846`](https://github.com/cloudflare/workers-sdk/commit/1db7846ec5c356f6b59cddf5f48b16b3e7c73d66) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore: update dependencies of "miniflare" package + + The following dependency versions have been updated: + + | Dependency | From | To | + | ------------------------- | ------------- | ------------- | + | workerd | 1.20241022.0 | 1.20241106.1 | + | @cloudflare/workers-types | ^4.20241022.0 | ^4.20241106.0 | + ## 3.20241022.0 ### Patch Changes diff --git a/packages/miniflare/package.json b/packages/miniflare/package.json index ef1823c96838..873f0b37d680 100644 --- a/packages/miniflare/package.json +++ b/packages/miniflare/package.json @@ -1,6 +1,6 @@ { "name": "miniflare", - "version": "3.20241022.0", + "version": "3.20241106.0", "description": "Fun, full-featured, fully-local simulator for Cloudflare Workers", "keywords": [ "cloudflare", diff --git a/packages/pages-shared/CHANGELOG.md b/packages/pages-shared/CHANGELOG.md index 33a25794c7fb..ec89fca54e9f 100644 --- a/packages/pages-shared/CHANGELOG.md +++ b/packages/pages-shared/CHANGELOG.md @@ -1,5 +1,12 @@ # @cloudflare/pages-shared +## 0.11.68 + +### Patch Changes + +- Updated dependencies [[`1db7846`](https://github.com/cloudflare/workers-sdk/commit/1db7846ec5c356f6b59cddf5f48b16b3e7c73d66)]: + - miniflare@3.20241106.0 + ## 0.11.67 ### Patch Changes diff --git a/packages/pages-shared/package.json b/packages/pages-shared/package.json index 728df270092d..aa20af76d2a1 100644 --- a/packages/pages-shared/package.json +++ b/packages/pages-shared/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/pages-shared", - "version": "0.11.67", + "version": "0.11.68", "repository": { "type": "git", "url": "https://github.com/cloudflare/workers-sdk.git", diff --git a/packages/vitest-pool-workers/CHANGELOG.md b/packages/vitest-pool-workers/CHANGELOG.md index b0ea74e2d27d..b1a86628aba5 100644 --- a/packages/vitest-pool-workers/CHANGELOG.md +++ b/packages/vitest-pool-workers/CHANGELOG.md @@ -1,5 +1,20 @@ # @cloudflare/vitest-pool-workers +## 0.5.27 + +### Patch Changes + +- Updated dependencies [[`b499b74`](https://github.com/cloudflare/workers-sdk/commit/b499b743e2720ca57e9f156f3e945a7d7afe98ac)]: + - wrangler@3.86.1 + +## 0.5.26 + +### Patch Changes + +- Updated dependencies [[`1db7846`](https://github.com/cloudflare/workers-sdk/commit/1db7846ec5c356f6b59cddf5f48b16b3e7c73d66), [`9098a3b`](https://github.com/cloudflare/workers-sdk/commit/9098a3b03f82bbfb1fb8c8c531fafbfe26a49e59), [`3dce388`](https://github.com/cloudflare/workers-sdk/commit/3dce3881bdaf373aa9b2e52483e340ab8193151c), [`ad51d1d`](https://github.com/cloudflare/workers-sdk/commit/ad51d1d77483bf0b4dc73fd392f5cdefe4ddf5d8), [`1d5bc6d`](https://github.com/cloudflare/workers-sdk/commit/1d5bc6d3530e98db117af3f6b16b43ff6c069f94), [`ef7c0b3`](https://github.com/cloudflare/workers-sdk/commit/ef7c0b3641925e2deceb7e5323f86b769de54405)]: + - miniflare@3.20241106.0 + - wrangler@3.86.0 + ## 0.5.25 ### Patch Changes diff --git a/packages/vitest-pool-workers/package.json b/packages/vitest-pool-workers/package.json index 4b30b03cc967..23f42998d54a 100644 --- a/packages/vitest-pool-workers/package.json +++ b/packages/vitest-pool-workers/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/vitest-pool-workers", - "version": "0.5.25", + "version": "0.5.27", "description": "Workers Vitest integration for writing Vitest unit and integration tests that run inside the Workers runtime", "keywords": [ "cloudflare", diff --git a/packages/workers-shared/CHANGELOG.md b/packages/workers-shared/CHANGELOG.md index 937d268fc052..0909fa1f846b 100644 --- a/packages/workers-shared/CHANGELOG.md +++ b/packages/workers-shared/CHANGELOG.md @@ -1,5 +1,11 @@ # @cloudflare/workers-shared +## 0.7.1 + +### Patch Changes + +- [#7183](https://github.com/cloudflare/workers-sdk/pull/7183) [`08c6580`](https://github.com/cloudflare/workers-sdk/commit/08c6580494e702373d17ff7485988a8fae9af59e) Thanks [@WillTaylorDev](https://github.com/WillTaylorDev)! - Fixes bug where indexId was never set for router-worker and asset-worker + ## 0.7.0 ### Minor Changes diff --git a/packages/workers-shared/asset-worker/tests/handler.test.ts b/packages/workers-shared/asset-worker/tests/handler.test.ts new file mode 100644 index 000000000000..5f31c39a14b6 --- /dev/null +++ b/packages/workers-shared/asset-worker/tests/handler.test.ts @@ -0,0 +1,99 @@ +import { vi } from "vitest"; +import { handleRequest } from "../src/handler"; +import type { AssetConfig } from "../../utils/types"; + +describe("[Asset Worker] `handleRequest`", () => { + it("attaches ETag headers to responses", async () => { + const configuration: Required = { + html_handling: "none", + not_found_handling: "none", + }; + const eTag = "some-etag"; + const exists = vi.fn().mockReturnValue(eTag); + const getByETag = vi.fn().mockReturnValue({ + readableStream: new ReadableStream(), + contentType: "text/html", + }); + + const response = await handleRequest( + new Request("https://example.com/"), + configuration, + exists, + getByETag + ); + + expect(response.headers.get("ETag")).toBe(`"${eTag}"`); + }); + + it("returns 304 Not Modified responses for a valid strong ETag in If-None-Match", async () => { + const configuration: Required = { + html_handling: "none", + not_found_handling: "none", + }; + const eTag = "some-etag"; + const exists = vi.fn().mockReturnValue(eTag); + const getByETag = vi.fn().mockReturnValue({ + readableStream: new ReadableStream(), + contentType: "text/html", + }); + + const response = await handleRequest( + new Request("https://example.com/", { + headers: { "If-None-Match": `"${eTag}"` }, + }), + configuration, + exists, + getByETag + ); + + expect(response.status).toBe(304); + }); + + it("returns 304 Not Modified responses for a valid weak ETag in If-None-Match", async () => { + const configuration: Required = { + html_handling: "none", + not_found_handling: "none", + }; + const eTag = "some-etag"; + const exists = vi.fn().mockReturnValue(eTag); + const getByETag = vi.fn().mockReturnValue({ + readableStream: new ReadableStream(), + contentType: "text/html", + }); + + const response = await handleRequest( + new Request("https://example.com/", { + headers: { "If-None-Match": `W/"${eTag}"` }, + }), + configuration, + exists, + getByETag + ); + + expect(response.status).toBe(304); + }); + + it("returns 200 OK responses for an invalid ETag in If-None-Match", async () => { + const configuration: Required = { + html_handling: "none", + not_found_handling: "none", + }; + const eTag = "some-etag"; + const exists = vi.fn().mockReturnValue(eTag); + const getByETag = vi.fn().mockReturnValue({ + readableStream: new ReadableStream(), + contentType: "text/html", + }); + + const response = await handleRequest( + new Request("https://example.com/", { + headers: { "If-None-Match": "a fake etag!" }, + }), + configuration, + exists, + getByETag + ); + + expect(response.status).toBe(200); + }); +}); diff --git a/packages/workers-shared/package.json b/packages/workers-shared/package.json index 61d5604e5f6d..608104f3eb8f 100644 --- a/packages/workers-shared/package.json +++ b/packages/workers-shared/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/workers-shared", - "version": "0.7.0", + "version": "0.7.1", "description": "Package that is used at Cloudflare to power some internal features of Cloudflare Workers.", "keywords": [ "cloudflare", diff --git a/packages/wrangler-devtools/CHANGELOG.md b/packages/wrangler-devtools/CHANGELOG.md index 72d2b95337d2..14c6e9dd761f 100644 --- a/packages/wrangler-devtools/CHANGELOG.md +++ b/packages/wrangler-devtools/CHANGELOG.md @@ -1,5 +1,15 @@ # @cloudflare/wrangler-devtools +## 0.1.0 + +### Minor Changes + +- [#7137](https://github.com/cloudflare/workers-sdk/pull/7137) [`1b195bd`](https://github.com/cloudflare/workers-sdk/commit/1b195bd09aef282a8a205d341579cdb7e3755d89) Thanks [@andyjessop](https://github.com/andyjessop)! - feat: update devtools patches for release + + - rebases patches on top of latest devtools head + - removes CPU profiling tab + - adds performance tab + ## 0.0.1 ### Patch Changes diff --git a/packages/wrangler-devtools/README.md b/packages/wrangler-devtools/README.md index 3f4365f7cda0..e0c5b810e3d1 100644 --- a/packages/wrangler-devtools/README.md +++ b/packages/wrangler-devtools/README.md @@ -52,9 +52,16 @@ Two methods are available for testing updates: **Preview Builds:** -- Add `preview:wrangler-devtools` label to PRs -- Use deployed preview URL for testing -- Verify functionality in Playground +On any pull request to the repo on GitHub, you can add labels to trigger preview builds of both the DevTools frontend, and the Playground. This is useful because it will allow you to manually test your changes in a live environment, and with one-click. + +There are two labels you can use: + +- `preview:wrangler-devtools` - this will trigger the DevTools preview +- `preview:wrangler-playground` - this will trigger the Playground preview + +If you add **both** labels, Playground will embed the DevTools preview, so you can test them together. + +Once the previews are built, you will see a comment on the PR with links to the live URLs. ## Acceptance Criteria diff --git a/packages/wrangler-devtools/package.json b/packages/wrangler-devtools/package.json index e0a1623eed4f..1e968fffa11b 100644 --- a/packages/wrangler-devtools/package.json +++ b/packages/wrangler-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/wrangler-devtools", - "version": "0.0.1", + "version": "0.1.0", "private": true, "description": "Chrome Devtools hosted for easy use with Wrangler", "homepage": "https://github.com/cloudflare/workers-sdk#readme", diff --git a/packages/wrangler/CHANGELOG.md b/packages/wrangler/CHANGELOG.md index 38cbfdd7fe4a..dcb7a3925c4c 100644 --- a/packages/wrangler/CHANGELOG.md +++ b/packages/wrangler/CHANGELOG.md @@ -1,5 +1,31 @@ # wrangler +## 3.86.1 + +### Patch Changes + +- [#7069](https://github.com/cloudflare/workers-sdk/pull/7069) [`b499b74`](https://github.com/cloudflare/workers-sdk/commit/b499b743e2720ca57e9f156f3e945a7d7afe98ac) Thanks [@penalosa](https://github.com/penalosa)! - Internal refactor to remove the non `--x-dev-env` flow from `wrangler dev` + +## 3.86.0 + +### Minor Changes + +- [#7154](https://github.com/cloudflare/workers-sdk/pull/7154) [`ef7c0b3`](https://github.com/cloudflare/workers-sdk/commit/ef7c0b3641925e2deceb7e5323f86b769de54405) Thanks [@jonesphillip](https://github.com/jonesphillip)! - Added the ability to enable, disable, and get r2.dev public access URLs for R2 buckets. + +### Patch Changes + +- [#7169](https://github.com/cloudflare/workers-sdk/pull/7169) [`9098a3b`](https://github.com/cloudflare/workers-sdk/commit/9098a3b03f82bbfb1fb8c8c531fafbfe26a49e59) Thanks [@penalosa](https://github.com/penalosa)! - Ensure `workerd` processes are cleaned up after address-in-use errors + +- [#7172](https://github.com/cloudflare/workers-sdk/pull/7172) [`3dce388`](https://github.com/cloudflare/workers-sdk/commit/3dce3881bdaf373aa9b2e52483e340ab8193151c) Thanks [@penalosa](https://github.com/penalosa)! - Clarify dev registry messaging around locally connected services. The connection status of local service bindings & durable object bindings is now indicated by `connected` or `not connected` next to their entry in the bindings summary. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development + +- [#7193](https://github.com/cloudflare/workers-sdk/pull/7193) [`ad51d1d`](https://github.com/cloudflare/workers-sdk/commit/ad51d1d77483bf0b4dc73fd392f5cdefe4ddf5d8) Thanks [@sdnts](https://github.com/sdnts)! - Output suggested wrangler.toml changes after creating an R2 bucket + +- [#7191](https://github.com/cloudflare/workers-sdk/pull/7191) [`1d5bc6d`](https://github.com/cloudflare/workers-sdk/commit/1d5bc6d3530e98db117af3f6b16b43ff6c069f94) Thanks [@sdnts](https://github.com/sdnts)! - Output suggested wrangler.toml changes after creating a Queue + +- Updated dependencies [[`1db7846`](https://github.com/cloudflare/workers-sdk/commit/1db7846ec5c356f6b59cddf5f48b16b3e7c73d66), [`08c6580`](https://github.com/cloudflare/workers-sdk/commit/08c6580494e702373d17ff7485988a8fae9af59e)]: + - miniflare@3.20241106.0 + - @cloudflare/workers-shared@0.7.1 + ## 3.85.0 ### Minor Changes diff --git a/packages/wrangler/e2e/__snapshots__/dev.test.ts.snap b/packages/wrangler/e2e/__snapshots__/dev.test.ts.snap index 49478b0d1529..befd125db475 100644 --- a/packages/wrangler/e2e/__snapshots__/dev.test.ts.snap +++ b/packages/wrangler/e2e/__snapshots__/dev.test.ts.snap @@ -1,49 +1,21 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > --test-scheduled works with wrangler dev --no-x-dev-env > custom build 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev --remote' > --test-scheduled works with wrangler dev --remote > custom build 1`] = `"Ran scheduled event"`; -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > --test-scheduled works with wrangler dev --no-x-dev-env > no custom build 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev --remote' > --test-scheduled works with wrangler dev --remote > no custom build 1`] = `"Ran scheduled event"`; -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > --test-scheduled works with wrangler dev --no-x-dev-env 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev --remote' > can modify worker during wrangler dev --remote 1`] = `"Hello World!"`; -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > can modify worker during wrangler dev --no-x-dev-env 1`] = `"Hello World!"`; +exports[`basic js dev: 'wrangler dev --remote' > can modify worker during wrangler dev --remote 2`] = `"Updated Worker! value"`; -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > can modify worker during wrangler dev --no-x-dev-env 2`] = `"Updated Worker! value"`; +exports[`basic js dev: 'wrangler dev --remote' > hotkeys can be disabled with wrangler dev --remote 1`] = `"Hello World!"`; -exports[`basic js dev: 'wrangler dev --no-x-dev-env' > hotkeys can be disabled with wrangler dev --no-x-dev-env 1`] = `"Hello World!"`; +exports[`basic js dev: 'wrangler dev' > --test-scheduled works with wrangler dev > custom build 1`] = `"Ran scheduled event"`; -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > --test-scheduled works with wrangler dev --remote --no-x-dev-env > custom build 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev' > --test-scheduled works with wrangler dev > no custom build 1`] = `"Ran scheduled event"`; -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > --test-scheduled works with wrangler dev --remote --no-x-dev-env > no custom build 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev' > can modify worker during wrangler dev 1`] = `"Hello World!"`; -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > --test-scheduled works with wrangler dev --remote --no-x-dev-env 1`] = `"Ran scheduled event"`; +exports[`basic js dev: 'wrangler dev' > can modify worker during wrangler dev 2`] = `"Updated Worker! value"`; -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > can modify worker during wrangler dev --remote --no-x-dev-env 1`] = `"Hello World!"`; - -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > can modify worker during wrangler dev --remote --no-x-dev-env 2`] = `"Updated Worker! value"`; - -exports[`basic js dev: 'wrangler dev --remote --no-x-dev-env' > hotkeys can be disabled with wrangler dev --remote --no-x-dev-env 1`] = `"Hello World!"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > --test-scheduled works with wrangler dev --remote --x-dev-env > custom build 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > --test-scheduled works with wrangler dev --remote --x-dev-env > no custom build 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > --test-scheduled works with wrangler dev --remote --x-dev-env 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > can modify worker during wrangler dev --remote --x-dev-env 1`] = `"Hello World!"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > can modify worker during wrangler dev --remote --x-dev-env 2`] = `"Updated Worker! value"`; - -exports[`basic js dev: 'wrangler dev --remote --x-dev-env' > hotkeys can be disabled with wrangler dev --remote --x-dev-env 1`] = `"Hello World!"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > --test-scheduled works with wrangler dev --x-dev-env > custom build 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > --test-scheduled works with wrangler dev --x-dev-env > no custom build 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > --test-scheduled works with wrangler dev --x-dev-env 1`] = `"Ran scheduled event"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > can modify worker during wrangler dev --x-dev-env 1`] = `"Hello World!"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > can modify worker during wrangler dev --x-dev-env 2`] = `"Updated Worker! value"`; - -exports[`basic js dev: 'wrangler dev --x-dev-env' > hotkeys can be disabled with wrangler dev --x-dev-env 1`] = `"Hello World!"`; +exports[`basic js dev: 'wrangler dev' > hotkeys can be disabled with wrangler dev 1`] = `"Hello World!"`; diff --git a/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap b/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap index 5dd2b4341d05..d55ad590a860 100644 --- a/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap +++ b/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap @@ -1,47 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Pages 'wrangler pages dev --no-x-dev-env' > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = ` -"✨ Compiled Worker successfully -▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed. - Be aware that changes to the data stored in these Durable Objects will be permanent and affect the live instances. - Remote Durable Objects that are affected: - - {"name":"DO_BINDING_1_TOML","class_name":"DO_1_TOML","script_name":"DO_SCRIPT_1_TOML"} - - {"name":"DO_BINDING_2_TOML","class_name":"DO_2_TOML","script_name":"DO_SCRIPT_2_TOML"} -▲ [WARNING] This worker is bound to live services: SERVICE_BINDING_1_TOML (SERVICE_NAME_1_TOML), SERVICE_BINDING_2_TOML (SERVICE_NAME_2_TOML) -Your worker has access to the following bindings: -- Durable Objects: - - DO_BINDING_1_TOML: NEW_DO_1 (defined in NEW_DO_SCRIPT_1 [not connected]) - - DO_BINDING_2_TOML: DO_2_TOML (defined in DO_SCRIPT_2_TOML [not connected]) - - DO_BINDING_3_ARGS: DO_3_ARGS (defined in DO_SCRIPT_3_ARGS [not connected]) -- KV Namespaces: - - KV_BINDING_1_TOML: NEW_KV_ID_1 (local) - - KV_BINDING_2_TOML: KV_ID_2_TOML (local) - - KV_BINDING_3_ARGS: KV_ID_3_ARGS (local) -- D1 Databases: - - D1_BINDING_1_TOML: local-D1_BINDING_1_TOML=NEW_D1_NAME_1 (NEW_D1_NAME_1) (local) - - D1_BINDING_2_TOML: D1_NAME_2_TOML (D1_ID_2_TOML) (local) - - D1_BINDING_3_ARGS: local-D1_BINDING_3_ARGS=D1_NAME_3_ARGS (D1_NAME_3_ARGS) (local) -- R2 Buckets: - - R2_BINDING_1_TOML: NEW_R2_BUCKET_1 (local) - - R2_BINDING_2_TOML: R2_BUCKET_2_TOML (local) - - R2_BINDING_3_TOML: R2_BUCKET_3_ARGS (local) -- Services: - - SERVICE_BINDING_1_TOML: NEW_SERVICE_NAME_1 [not connected] - - SERVICE_BINDING_2_TOML: SERVICE_NAME_2_TOML [not connected] - - SERVICE_BINDING_3_TOML: SERVICE_NAME_3_ARGS [not connected] -- AI: - - Name: AI_BINDING_2_TOML -- Vars: - - VAR1: "(hidden)" - - VAR2: "VAR_2_TOML" - - VAR3: "(hidden)" -Service bindings & durable object bindings connect to other \`wrangler dev\` processes running locally, with their connection status indicated by [connected] or [not connected]. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development -▲ [WARNING] ⎔ Support for service bindings in local mode is experimental and may change. -▲ [WARNING] ⎔ Support for external Durable Objects in local mode is experimental and may change. -" -`; - -exports[`Pages 'wrangler pages dev --x-dev-env' > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = ` +exports[`Pages 'wrangler pages dev' > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = ` "✨ Compiled Worker successfully ▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed. Be aware that changes to the data stored in these Durable Objects will be permanent and affect the live instances. diff --git a/packages/wrangler/e2e/c3-integration.test.ts b/packages/wrangler/e2e/c3-integration.test.ts index ad9ea2ec4513..8dc51b8d1549 100644 --- a/packages/wrangler/e2e/c3-integration.test.ts +++ b/packages/wrangler/e2e/c3-integration.test.ts @@ -1,13 +1,14 @@ import assert from "node:assert"; import { execSync } from "node:child_process"; -import { existsSync } from "node:fs"; +import { readFileSync } from "node:fs"; import path from "node:path"; import { fetch } from "undici"; import { beforeAll, describe, expect, it } from "vitest"; import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test"; import { generateResourceName } from "./helpers/generate-resource-name"; -describe("c3 integration", () => { +// TODO: Investigate why this is really flaky on windows +describe.runIf(process.platform !== "win32")("c3 integration", () => { const helper = new WranglerE2ETestHelper(); const workerName = generateResourceName("c3"); let c3Packed: string; @@ -39,8 +40,11 @@ describe("c3 integration", () => { }); expect( - existsSync(path.join(helper.tmpPath, workerName, "wrangler.toml")) - ).toBe(true); + readFileSync( + path.join(helper.tmpPath, workerName, "wrangler.toml"), + "utf8" + ) + ).not.toContain(""); }); it("can run `wrangler dev` on generated worker", async () => { diff --git a/packages/wrangler/e2e/dev-registry.test.ts b/packages/wrangler/e2e/dev-registry.test.ts index a24f89b62138..aab29e3edb72 100644 --- a/packages/wrangler/e2e/dev-registry.test.ts +++ b/packages/wrangler/e2e/dev-registry.test.ts @@ -1,3 +1,4 @@ +import { execSync } from "child_process"; import dedent from "ts-dedent"; import { fetch } from "undici"; import { beforeEach, describe, expect, it, vi } from "vitest"; @@ -5,7 +6,8 @@ import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test"; import { fetchText } from "./helpers/fetch-text"; import { generateResourceName } from "./helpers/generate-resource-name"; import { normalizeOutput } from "./helpers/normalize"; -import { seed as baseSeed, makeRoot } from "./helpers/setup"; +import { seed as baseSeed, makeRoot, seed } from "./helpers/setup"; +import { WRANGLER_IMPORT } from "./helpers/wrangler"; import type { RequestInit } from "undici"; async function fetchJson(url: string, info?: RequestInit): Promise { @@ -27,6 +29,114 @@ async function fetchJson(url: string, info?: RequestInit): Promise { ); } +describe("unstable_dev()", () => { + let parent: string; + let child: string; + let workerName: string; + + beforeEach(async () => { + workerName = generateResourceName("worker"); + + parent = makeRoot(); + + await seed(parent, { + "wrangler.toml": dedent` + name = "app" + compatibility_date = "2023-01-01" + compatibility_flags = ["nodejs_compat"] + + [[services]] + binding = "WORKER" + service = '${workerName}' + `, + "src/index.ts": dedent/* javascript */ ` + export default { + async fetch(req, env) { + return new Response("Hello from Parent!" + await env.WORKER.fetch(req).then(r => r.text())) + }, + }; + `, + "package.json": dedent` + { + "name": "app", + "version": "0.0.0", + "private": true + } + `, + }); + + child = await makeRoot(); + await seed(child, { + "wrangler.toml": dedent` + name = "${workerName}" + main = "src/index.ts" + compatibility_date = "2023-01-01" + `, + "src/index.ts": dedent/* javascript */ ` + export default { + fetch(req, env) { + return new Response("Hello from Child!") + }, + }; + `, + "package.json": dedent` + { + "name": "${workerName}", + "version": "0.0.0", + "private": true + } + `, + }); + }); + + async function runInNode() { + await seed(parent, { + "index.mjs": dedent/*javascript*/ ` + import { unstable_dev } from "${WRANGLER_IMPORT}" + import { setTimeout } from "node:timers/promises"; + + const childWorker = await unstable_dev( + "${child.replaceAll("\\", "/")}/src/index.ts", + { + configPath: "${child.replaceAll("\\", "/")}/wrangler.toml", + experimental: { + disableExperimentalWarning: true, + }, + } + ); + + const parentWorker = await unstable_dev( + "src/index.ts", + { + configPath: "wrangler.toml", + experimental: { + disableExperimentalWarning: true, + }, + } + ); + + await setTimeout(2000) + + console.log(await parentWorker.fetch("/").then(r => r.text())) + + process.exit(0); + `, + }); + const stdout = execSync(`node index.mjs`, { + cwd: parent, + encoding: "utf-8", + }); + return stdout; + } + + it("can fetch child", async () => { + await expect(runInNode()).resolves.toMatchInlineSnapshot(` + "Hello from Parent!Hello from Child! + " + `); + }); +}); + describe.each([ { cmd: "wrangler dev --x-registry" }, { cmd: "wrangler dev --no-x-registry" }, diff --git a/packages/wrangler/e2e/dev-with-resources.test.ts b/packages/wrangler/e2e/dev-with-resources.test.ts index dfcd6dea5e77..793995073aca 100644 --- a/packages/wrangler/e2e/dev-with-resources.test.ts +++ b/packages/wrangler/e2e/dev-with-resources.test.ts @@ -9,10 +9,8 @@ import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test"; import { generateResourceName } from "./helpers/generate-resource-name"; const RUNTIMES = [ - { flags: "--no-x-dev-env", runtime: "local" }, - { flags: "--remote --no-x-dev-env", runtime: "remote" }, - { flags: "--x-dev-env", runtime: "local" }, - { flags: "--remote --x-dev-env", runtime: "remote" }, + { flags: "", runtime: "local" }, + { flags: "--remote", runtime: "remote" }, ] as const; // WebAssembly module containing single `func add(i32, i32): i32` export. diff --git a/packages/wrangler/e2e/dev.test.ts b/packages/wrangler/e2e/dev.test.ts index e586f985c7b7..ee2c587e3e40 100644 --- a/packages/wrangler/e2e/dev.test.ts +++ b/packages/wrangler/e2e/dev.test.ts @@ -52,16 +52,13 @@ it("can import URL from 'url' in node_compat mode", async () => { ); }); -describe.each([ - { cmd: "wrangler dev --no-x-dev-env" }, - { cmd: "wrangler dev --remote --no-x-dev-env" }, - { cmd: "wrangler dev --x-dev-env" }, - { cmd: "wrangler dev --remote --x-dev-env" }, -])("basic js dev: $cmd", ({ cmd }) => { - it(`can modify worker during ${cmd}`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` +describe.each([{ cmd: "wrangler dev" }, { cmd: "wrangler dev --remote" }])( + "basic js dev: $cmd", + ({ cmd }) => { + it(`can modify worker during ${cmd}`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" @@ -70,44 +67,44 @@ describe.each([ [vars] KEY = "value" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello World!") } }`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(cmd); + }); + const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect(fetch(url).then((r) => r.text())).resolves.toMatchSnapshot(); + await expect(fetch(url).then((r) => r.text())).resolves.toMatchSnapshot(); - await helper.seed({ - "src/index.ts": dedent` + await helper.seed({ + "src/index.ts": dedent` export default { fetch(request, env) { return new Response("Updated Worker! " + env.KEY) } }`, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - await expect(fetchText(url)).resolves.toMatchSnapshot(); - }); + await expect(fetchText(url)).resolves.toMatchSnapshot(); + }); - it(`hotkeys can be disabled with ${cmd}`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`hotkeys can be disabled with ${cmd}`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" @@ -116,101 +113,102 @@ describe.each([ [vars] KEY = "value" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello World!") } }`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived( - `${cmd} --show-interactive-dev-session=false` - ); + }); + const worker = helper.runLongLived( + `${cmd} --show-interactive-dev-session=false` + ); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect(fetch(url).then((r) => r.text())).resolves.toMatchSnapshot(); + await expect(fetch(url).then((r) => r.text())).resolves.toMatchSnapshot(); - await expect(worker.currentOutput).not.toContain("[b] open a browser"); - }); + await expect(worker.currentOutput).not.toContain("[b] open a browser"); + }); - describe(`--test-scheduled works with ${cmd}`, async () => { - it("custom build", async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe(`--test-scheduled works with ${cmd}`, async () => { + it("custom build", async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" [build] command = "true" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { scheduled(event) { console.log("Event triggered") } }`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(`${cmd} --test-scheduled`); + }); + const worker = helper.runLongLived(`${cmd} --test-scheduled`); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect( - fetch(`${url}/__scheduled`).then((r) => r.text()) - ).resolves.toMatchSnapshot(); + await expect( + fetch(`${url}/__scheduled`).then((r) => r.text()) + ).resolves.toMatchSnapshot(); - await worker.readUntil(/Event triggered/); - }); + await worker.readUntil(/Event triggered/); + }); - it("no custom build", async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it("no custom build", async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { scheduled(event) { console.log("Event triggered") } }`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(`${cmd} --test-scheduled`); + }); + const worker = helper.runLongLived(`${cmd} --test-scheduled`); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect( - fetch(`${url}/__scheduled`).then((r) => r.text()) - ).resolves.toMatchSnapshot(); + await expect( + fetch(`${url}/__scheduled`).then((r) => r.text()) + ).resolves.toMatchSnapshot(); - await worker.readUntil(/Event triggered/); + await worker.readUntil(/Event triggered/); + }); }); - }); -}); + } +); interface Process { pid: string; @@ -310,115 +308,116 @@ it.runIf(process.platform !== "win32")( // Skipping remote python tests because they consistently flake with timeouts // Unskip once remote dev with python workers is more stable -describe.each([ - { cmd: "wrangler dev --no-x-dev-env" }, - { cmd: "wrangler dev --x-dev-env" }, -])("basic python dev: $cmd", { timeout: 90_000 }, ({ cmd }) => { - it(`can modify entrypoint during ${cmd}`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` +describe.each([{ cmd: "wrangler dev" }])( + "basic python dev: $cmd", + { timeout: 90_000 }, + ({ cmd }) => { + it(`can modify entrypoint during ${cmd}`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "index.py" compatibility_date = "2023-01-01" compatibility_flags = ["python_workers"] `, - "arithmetic.py": dedent` + "arithmetic.py": dedent` def mul(a,b): return a*b`, - "index.py": dedent` + "index.py": dedent` from arithmetic import mul from js import Response def on_fetch(request): return Response.new(f"py hello world {mul(2,3)}")`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(cmd); + }); + const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect(fetchText(url)).resolves.toBe("py hello world 6"); + await expect(fetchText(url)).resolves.toBe("py hello world 6"); - await helper.seed({ - "index.py": dedent` + await helper.seed({ + "index.py": dedent` from js import Response def on_fetch(request): return Response.new('Updated Python Worker value')`, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - // TODO(soon): work out why python workers need this retry before returning new content - const { text } = await retry( - (s) => s.status !== 200 || s.text === "py hello world 6", - async () => { - const r = await fetch(url); - return { text: await r.text(), status: r.status }; - } - ); + // TODO(soon): work out why python workers need this retry before returning new content + const { text } = await retry( + (s) => s.status !== 200 || s.text === "py hello world 6", + async () => { + const r = await fetch(url); + return { text: await r.text(), status: r.status }; + } + ); - expect(text).toBe("Updated Python Worker value"); - }); + expect(text).toBe("Updated Python Worker value"); + }); - it(`can modify imports during ${cmd}`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`can modify imports during ${cmd}`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "index.py" compatibility_date = "2023-01-01" compatibility_flags = ["python_workers"] `, - "arithmetic.py": dedent` + "arithmetic.py": dedent` def mul(a,b): return a*b`, - "index.py": dedent` + "index.py": dedent` from arithmetic import mul from js import Response def on_fetch(request): return Response.new(f"py hello world {mul(2,3)}")`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(cmd); + }); + const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - await expect(fetchText(url)).resolves.toBe("py hello world 6"); + await expect(fetchText(url)).resolves.toBe("py hello world 6"); - await helper.seed({ - "arithmetic.py": dedent` + await helper.seed({ + "arithmetic.py": dedent` def mul(a,b): return a+b`, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - // TODO(soon): work out why python workers need this retry before returning new content - const { text } = await retry( - (s) => s.status !== 200 || s.text === "py hello world 6", - async () => { - const r = await fetch(url); - return { text: await r.text(), status: r.status }; - } - ); + // TODO(soon): work out why python workers need this retry before returning new content + const { text } = await retry( + (s) => s.status !== 200 || s.text === "py hello world 6", + async () => { + const r = await fetch(url); + return { text: await r.text(), status: r.status }; + } + ); - expect(text).toBe("py hello world 5"); - }); -}); + expect(text).toBe("py hello world 5"); + }); + } +); describe("hyperdrive dev tests", () => { let server: nodeNet.Server; @@ -700,17 +699,14 @@ describe("writes debug logs to hidden file", () => { }); describe("analytics engine", () => { - describe.each([ - { cmd: "wrangler dev" }, - { cmd: "wrangler dev --x-dev-env" }, - { cmd: "wrangler dev --remote" }, - { cmd: "wrangler dev --remote --x-dev-env" }, - ])("mock analytics engine datasets: $cmd", ({ cmd }) => { - describe("module worker", () => { - it("analytics engine datasets are mocked in dev", async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe.each([{ cmd: "wrangler dev" }, { cmd: "wrangler dev --remote" }])( + "mock analytics engine datasets: $cmd", + ({ cmd }) => { + describe("module worker", () => { + it("analytics engine datasets are mocked in dev", async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2024-08-08" @@ -719,7 +715,7 @@ describe("analytics engine", () => { binding = "ANALYTICS_BINDING" dataset = "ANALYTICS_DATASET" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request, env) { // let's make an analytics call @@ -732,30 +728,30 @@ describe("analytics engine", () => { return new Response("successfully wrote datapoint from module worker"); } }`, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(cmd); + }); + const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - const text = await fetchText(url); - expect(text).toContain( - `successfully wrote datapoint from module worker` - ); + const text = await fetchText(url); + expect(text).toContain( + `successfully wrote datapoint from module worker` + ); + }); }); - }); - describe("service worker", async () => { - it("analytics engine datasets are mocked in dev", async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe("service worker", async () => { + it("analytics engine datasets are mocked in dev", async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2024-08-08" @@ -764,7 +760,7 @@ describe("analytics engine", () => { binding = "ANALYTICS_BINDING" dataset = "ANALYTICS_DATASET" `, - "src/index.ts": dedent` + "src/index.ts": dedent` addEventListener("fetch", (event) => { // let's make an analytics call ANALYTICS_BINDING.writeDataPoint({ @@ -776,25 +772,26 @@ describe("analytics engine", () => { event.respondWith(new Response("successfully wrote datapoint from service worker")); }); `, - "package.json": dedent` + "package.json": dedent` { "name": "worker", "version": "0.0.0", "private": true } `, - }); - const worker = helper.runLongLived(cmd); + }); + const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - const text = await fetchText(url); - expect(text).toContain( - `successfully wrote datapoint from service worker` - ); + const text = await fetchText(url); + expect(text).toContain( + `successfully wrote datapoint from service worker` + ); + }); }); - }); - }); + } + ); }); describe("zone selection", () => { @@ -1038,106 +1035,105 @@ describe("custom builds", () => { }); describe("watch mode", () => { - describe.each([ - { cmd: "wrangler dev" }, - { cmd: "wrangler dev --no-x-dev-env" }, - ])("Workers watch mode: $cmd", ({ cmd }) => { - it(`supports modifying the Worker script during dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe.each([{ cmd: "wrangler dev" }])( + "Workers watch mode: $cmd", + ({ cmd }) => { + it(`supports modifying the Worker script during dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/workerA.ts" compatibility_date = "2023-01-01" `, - "src/workerA.ts": dedent` + "src/workerA.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker A!") } }`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let text = await fetchText(url); - expect(text).toBe("Hello from user Worker A!"); + let text = await fetchText(url); + expect(text).toBe("Hello from user Worker A!"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/workerB.ts" compatibility_date = "2023-01-01" `, - "src/workerB.ts": dedent` + "src/workerB.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker B!") } }`, - }); + }); - await worker.waitForReload(); - text = await retry( - (s) => s != "Hello from user Worker B!", - async () => { - return await fetchText(url); - } - ); - expect(text).toBe("Hello from user Worker B!"); - }); - }); + await worker.waitForReload(); + text = await retry( + (s) => s != "Hello from user Worker B!", + async () => { + return await fetchText(url); + } + ); + expect(text).toBe("Hello from user Worker B!"); + }); + } + ); - describe.each([ - { cmd: "wrangler dev" }, - { cmd: "wrangler dev --no-x-dev-env" }, - ])("Workers + Assets watch mode: $cmd", ({ cmd }) => { - it(`supports modifying existing assets during dev session and errors when invalid routes are added`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe.each([{ cmd: "wrangler dev" }])( + "Workers + Assets watch mode: $cmd", + ({ cmd }) => { + it(`supports modifying existing assets during dev session and errors when invalid routes are added`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let { response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - {} - ); - const originalETag = response.headers.get("etag"); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + let { response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + {} + ); + const originalETag = response.headers.get("etag"); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - await helper.seed({ - "public/index.html": dedent` + await helper.seed({ + "public/index.html": dedent`

Hello Updated Workers + Assets

`, - }); + }); - await worker.waitForReload(); - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 200, - async () => { - return await fetchWithETag(`${url}/index.html`, cachedETags); - } - )); - expect(await response.text()).toBe( - "

Hello Updated Workers + Assets

" - ); - // expect a new eTag back because the content for this path has changed - expect(response.headers.get("etag")).not.toBe(originalETag); + await worker.waitForReload(); + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 200, + async () => { + return await fetchWithETag(`${url}/index.html`, cachedETags); + } + )); + expect(await response.text()).toBe( + "

Hello Updated Workers + Assets

" + ); + // expect a new eTag back because the content for this path has changed + expect(response.headers.get("etag")).not.toBe(originalETag); - // changes to routes should error while in watch mode - await helper.seed({ - "wrangler.toml": dedent` + // changes to routes should error while in watch mode + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" route = "example.com/path/*" @@ -1145,263 +1141,263 @@ describe("watch mode", () => { [assets] directory = "./public" `, + }); + await worker.readUntil(/Invalid Routes:/); }); - await worker.readUntil(/Invalid Routes:/); - }); - it(`supports adding new assets during dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports adding new assets during dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); - let { response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - {} - ); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); + let { response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + {} + ); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - await helper.seed({ - "public/about.html": dedent`About Workers + Assets`, - "public/workers/index.html": dedent`Cloudflare Workers!`, - }); + await helper.seed({ + "public/about.html": dedent`About Workers + Assets`, + "public/workers/index.html": dedent`Cloudflare Workers!`, + }); - await worker.waitForReload(); + await worker.waitForReload(); - // re-calculating the asset manifest / reverse assets map might not be - // done at this point, so retry until they are available - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 200, - async () => { - return await fetchWithETag(`${url}/about.html`, cachedETags); - } - )); - expect(await response.text()).toBe("About Workers + Assets"); - - ({ response, cachedETags } = await fetchWithETag( - `${url}/workers/index.html`, - cachedETags - )); - expect(await response.text()).toBe("Cloudflare Workers!"); - - // expect 304 for the original asset as the content has not changed - ({ response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - cachedETags - )); - expect(response.status).toBe(304); - }); + // re-calculating the asset manifest / reverse assets map might not be + // done at this point, so retry until they are available + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 200, + async () => { + return await fetchWithETag(`${url}/about.html`, cachedETags); + } + )); + expect(await response.text()).toBe("About Workers + Assets"); + + ({ response, cachedETags } = await fetchWithETag( + `${url}/workers/index.html`, + cachedETags + )); + expect(await response.text()).toBe("Cloudflare Workers!"); + + // expect 304 for the original asset as the content has not changed + ({ response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + cachedETags + )); + expect(response.status).toBe(304); + }); - it(`supports removing existing assets during dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports removing existing assets during dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - "public/about.html": dedent`About Workers + Assets`, - "public/workers/index.html": dedent`Cloudflare Workers!`, - }); + "public/about.html": dedent`About Workers + Assets`, + "public/workers/index.html": dedent`Cloudflare Workers!`, + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); - let { response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - {} - ); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); + let { response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + {} + ); + expect(await response.text()).toBe("

Hello Workers + Assets

"); + + ({ response, cachedETags } = await fetchWithETag( + `${url}/about.html`, + cachedETags + )); + expect(await response.text()).toBe("About Workers + Assets"); + ({ response, cachedETags } = await fetchWithETag( + `${url}/workers/index.html`, + cachedETags + )); + expect(await response.text()).toBe("Cloudflare Workers!"); + + await helper.removeFiles(["public/index.html"]); + + await worker.waitForReload(); + + // re-calculating the asset manifest / reverse assets map might not be + // done at this point, so retry until they are available + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 404, + async () => { + return await fetchWithETag(`${url}/index.html`, cachedETags); + } + )); + expect(response.status).toBe(404); + }); - ({ response, cachedETags } = await fetchWithETag( - `${url}/about.html`, - cachedETags - )); - expect(await response.text()).toBe("About Workers + Assets"); - ({ response, cachedETags } = await fetchWithETag( - `${url}/workers/index.html`, - cachedETags - )); - expect(await response.text()).toBe("Cloudflare Workers!"); - - await helper.removeFiles(["public/index.html"]); - - await worker.waitForReload(); - - // re-calculating the asset manifest / reverse assets map might not be - // done at this point, so retry until they are available - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 404, - async () => { - return await fetchWithETag(`${url}/index.html`, cachedETags); - } - )); - expect(response.status).toBe(404); - }); - - it(`supports modifying the assets directory in wrangler.toml during dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports modifying the assets directory in wrangler.toml during dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); - await helper.seed({ - "public2/index.html": dedent` + }); + await helper.seed({ + "public2/index.html": dedent`

Hola Workers + Assets

`, - "public2/about/index.html": dedent` + "public2/about/index.html": dedent`

Read more about Workers + Assets

`, - }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + }); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let { response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - {} - ); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + let { response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + {} + ); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public2" `, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 200, - async () => { - return await fetchWithETag(`${url}/index.html`, cachedETags); - } - )); - expect(await response.text()).toBe("

Hola Workers + Assets

"); - ({ response, cachedETags } = await fetchWithETag( - `${url}/about/index.html`, - {} - )); - expect(await response.text()).toBe( - "

Read more about Workers + Assets

" - ); - }); + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 200, + async () => { + return await fetchWithETag(`${url}/index.html`, cachedETags); + } + )); + expect(await response.text()).toBe("

Hola Workers + Assets

"); + ({ response, cachedETags } = await fetchWithETag( + `${url}/about/index.html`, + {} + )); + expect(await response.text()).toBe( + "

Read more about Workers + Assets

" + ); + }); - it(`supports switching from Workers without assets to assets-only Workers during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from Workers without assets to assets-only Workers during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + let response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); - - await worker.waitForReload(); + }); - // verify response from Asset Worker - const { status, text } = await retry( - (s) => s.text !== "

Hello Workers + Assets

", - async () => { - const fetchResponse = await fetch(url); - return { - status: fetchResponse.status, - text: await fetchResponse.text(), - }; - } - ); - expect(status).toBe(200); - expect(text).toBe("

Hello Workers + Assets

"); + await worker.waitForReload(); + + // verify response from Asset Worker + const { status, text } = await retry( + (s) => s.text !== "

Hello Workers + Assets

", + async () => { + const fetchResponse = await fetch(url); + return { + status: fetchResponse.status, + text: await fetchResponse.text(), + }; + } + ); + expect(status).toBe(200); + expect(text).toBe("

Hello Workers + Assets

"); - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify we no longer get a response from the User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(404); - }); + // verify we no longer get a response from the User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(404); + }); - it(`supports switching from Workers without assets to Workers with assets during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from Workers without assets to Workers with assets during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + let response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" @@ -1409,64 +1405,64 @@ describe("watch mode", () => { [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); - - await worker.waitForReload(); + }); - // verify response from Asset Worker - const { status, text } = await retry( - (s) => s.text !== "

Hello Workers + Assets

", - async () => { - const fetchResponse = await fetch(url); - return { - status: fetchResponse.status, - text: await fetchResponse.text(), - }; - } - ); - expect(status).toBe(200); - expect(text).toBe("

Hello Workers + Assets

"); + await worker.waitForReload(); + + // verify response from Asset Worker + const { status, text } = await retry( + (s) => s.text !== "

Hello Workers + Assets

", + async () => { + const fetchResponse = await fetch(url); + return { + status: fetchResponse.status, + text: await fetchResponse.text(), + }; + } + ); + expect(status).toBe(200); + expect(text).toBe("

Hello Workers + Assets

"); - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify response from the User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); - }); + // verify response from the User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); + }); - it(`supports switching from assets-only Workers to Workers with assets during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from assets-only Workers to Workers with assets during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + }); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - // verify response from Asset Worker - let response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify response from Asset Worker + let response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify no response from route that will be handled by the - // User Worker in the future - response = await fetch(`${url}/hey`); - expect(response.status).toBe(404); + // verify no response from route that will be handled by the + // User Worker in the future + response = await fetch(`${url}/hey`); + expect(response.status).toBe(404); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" @@ -1474,31 +1470,31 @@ describe("watch mode", () => { [assets] directory = "./public" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - // verify we still get the correct response for the Asset Worker - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify we still get the correct response for the Asset Worker + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify response from User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); - }); + // verify response from User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); + }); - it(`supports switching from Workers with assets to assets-only Workers during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from Workers with assets to assets-only Workers during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" @@ -1506,55 +1502,55 @@ describe("watch mode", () => { [assets] directory = "./public" `, - "public/index.html": dedent` + "public/index.html": dedent`

Hello Workers + Assets

`, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - // verify response from Asset Worker - let response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify response from Asset Worker + let response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify response from User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + // verify response from User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" [assets] directory = "./public" `, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - // verify we still get the correct response from Asset Worker - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify we still get the correct response from Asset Worker + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify we no longer get a response from the User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(404); - }); + // verify we no longer get a response from the User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(404); + }); - it("debounces runtime restarts when assets are modified", async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it("debounces runtime restarts when assets are modified", async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" main = "src/index.ts" @@ -1562,237 +1558,238 @@ describe("watch mode", () => { [assets] directory = "./public" `, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { async fetch(request) { return new Response("Hello, World!") } } `, - "public/index.html": "Hello from Assets", - }); - const worker = helper.runLongLived("wrangler dev"); + "public/index.html": "Hello from Assets", + }); + const worker = helper.runLongLived("wrangler dev"); - const { url } = await worker.waitForReady(); + const { url } = await worker.waitForReady(); - // Modify assets multiple times in quick succession + // Modify assets multiple times in quick succession - await helper.seed({ - "public/a.html": "a", - }); + await helper.seed({ + "public/a.html": "a", + }); - await helper.seed({ - "public/b.html": "b", - }); + await helper.seed({ + "public/b.html": "b", + }); - await helper.seed({ - "public/c.html": "c", - }); + await helper.seed({ + "public/c.html": "c", + }); - await worker.waitForReload(); + await worker.waitForReload(); - // The three changes should be debounced, so only one reload should occur - await expect(worker.waitForReload(5_000)).rejects.toThrowError(); + // The three changes should be debounced, so only one reload should occur + await expect(worker.waitForReload(5_000)).rejects.toThrowError(); - // now check assets are still fetchable - await expect(fetchText(url)).resolves.toBe("Hello from Assets"); - }); - }); + // now check assets are still fetchable + await expect(fetchText(url)).resolves.toBe("Hello from Assets"); + }); + } + ); - describe.each([ - { cmd: "wrangler dev --assets=dist" }, - { cmd: "wrangler dev --x-dev-env --assets=dist" }, - ])("Workers + Assets watch mode: $cmd", ({ cmd }) => { - it(`supports modifying assets during dev session and errors when invalid routes are added`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + describe.each([{ cmd: "wrangler dev --assets=dist" }])( + "Workers + Assets watch mode: $cmd", + ({ cmd }) => { + it(`supports modifying assets during dev session and errors when invalid routes are added`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" `, - "dist/index.html": dedent` + "dist/index.html": dedent`

Hello Workers + Assets

`, - "dist/about.html": dedent` + "dist/about.html": dedent`

Read more about Workers + Assets

`, - }); + }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - let { response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - {} - ); - const originalETag = response.headers.get("etag"); - expect(await response.text()).toBe("

Hello Workers + Assets

"); - - ({ response, cachedETags } = await fetchWithETag( - `${url}/about.html`, - cachedETags - )); - expect(await response.text()).toBe( - "

Read more about Workers + Assets

" - ); + let { response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + {} + ); + const originalETag = response.headers.get("etag"); + expect(await response.text()).toBe("

Hello Workers + Assets

"); + + ({ response, cachedETags } = await fetchWithETag( + `${url}/about.html`, + cachedETags + )); + expect(await response.text()).toBe( + "

Read more about Workers + Assets

" + ); - // change + add - await helper.seed({ - "dist/index.html": dedent` + // change + add + await helper.seed({ + "dist/index.html": dedent`

Hello Updated Workers + Assets

`, - "dist/hello.html": dedent` + "dist/hello.html": dedent`

Hya Workers!

`, - }); - - await worker.waitForReload(); - - // re-calculating the asset manifest / reverse assets map might not be - // done at this point, so retry until they are available - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 200, - async () => { - return await fetchWithETag(`${url}/hello.html`, cachedETags); - } - )); - expect(await response.text()).toBe("

Hya Workers!

"); - - ({ response, cachedETags } = await fetchWithETag( - `${url}/index.html`, - cachedETags - )); - expect(await response.text()).toBe( - "

Hello Updated Workers + Assets

" - ); - expect(response.headers.get("etag")).not.toBe(originalETag); - - // unchanged -> expect 304 - ({ response, cachedETags } = await fetchWithETag( - `${url}/about.html`, - cachedETags - )); - expect(response.status).toBe(304); + }); - // remove - await helper.removeFiles(["dist/about.html"]); + await worker.waitForReload(); - await worker.waitForReload(); - - // re-calculating the asset manifest / reverse assets map might not be - // done at this point, so retry until they are available - ({ response, cachedETags } = await retry( - (s) => s.response.status !== 404, - async () => { - return await fetchWithETag(`${url}/about.html`, cachedETags); - } - )); - expect(response.status).toBe(404); + // re-calculating the asset manifest / reverse assets map might not be + // done at this point, so retry until they are available + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 200, + async () => { + return await fetchWithETag(`${url}/hello.html`, cachedETags); + } + )); + expect(await response.text()).toBe("

Hya Workers!

"); + + ({ response, cachedETags } = await fetchWithETag( + `${url}/index.html`, + cachedETags + )); + expect(await response.text()).toBe( + "

Hello Updated Workers + Assets

" + ); + expect(response.headers.get("etag")).not.toBe(originalETag); + + // unchanged -> expect 304 + ({ response, cachedETags } = await fetchWithETag( + `${url}/about.html`, + cachedETags + )); + expect(response.status).toBe(304); + + // remove + await helper.removeFiles(["dist/about.html"]); + + await worker.waitForReload(); + + // re-calculating the asset manifest / reverse assets map might not be + // done at this point, so retry until they are available + ({ response, cachedETags } = await retry( + (s) => s.response.status !== 404, + async () => { + return await fetchWithETag(`${url}/about.html`, cachedETags); + } + )); + expect(response.status).toBe(404); - // changes to routes should error while in watch mode - await helper.seed({ - "wrangler.toml": dedent` + // changes to routes should error while in watch mode + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" route = "example.com/path/*" `, + }); + await worker.readUntil(/Invalid Routes:/); }); - await worker.readUntil(/Invalid Routes:/); - }); - it(`supports switching from assets-only Workers to Workers with assets during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from assets-only Workers to Workers with assets during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" `, - "dist/index.html": dedent` + "dist/index.html": dedent`

Hello Workers + Assets

`, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + }); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - // verify response from Asset Worker - let response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify response from Asset Worker + let response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify no response from route that will be handled by the - // User Worker in the future - response = await fetch(`${url}/hey`); - expect(response.status).toBe(404); + // verify no response from route that will be handled by the + // User Worker in the future + response = await fetch(`${url}/hey`); + expect(response.status).toBe(404); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" `, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - // verify response from Asset Worker - response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify response from Asset Worker + response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify response from User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); - }); + // verify response from User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); + }); - it(`supports switching from Workers with assets to assets-only Workers during the current dev session`, async () => { - const helper = new WranglerE2ETestHelper(); - await helper.seed({ - "wrangler.toml": dedent` + it(`supports switching from Workers with assets to assets-only Workers during the current dev session`, async () => { + const helper = new WranglerE2ETestHelper(); + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" main = "src/index.ts" compatibility_date = "2023-01-01" `, - "dist/index.html": dedent` + "dist/index.html": dedent`

Hello Workers + Assets

`, - "src/index.ts": dedent` + "src/index.ts": dedent` export default { fetch(request) { return new Response("Hello from user Worker!") } }`, - }); - const worker = helper.runLongLived(cmd); - const { url } = await worker.waitForReady(); + }); + const worker = helper.runLongLived(cmd); + const { url } = await worker.waitForReady(); - // verify response from Asset Worker - let response = await fetch(`${url}/index.html`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + // verify response from Asset Worker + let response = await fetch(`${url}/index.html`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify response from User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(200); - expect(await response.text()).toBe("Hello from user Worker!"); + // verify response from User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello from user Worker!"); - await helper.seed({ - "wrangler.toml": dedent` + await helper.seed({ + "wrangler.toml": dedent` name = "${workerName}" compatibility_date = "2023-01-01" `, - }); + }); - await worker.waitForReload(); + await worker.waitForReload(); - response = await fetch(`${url}/index.html`); - // verify response from Asset - expect(response.status).toBe(200); - expect(await response.text()).toBe("

Hello Workers + Assets

"); + response = await fetch(`${url}/index.html`); + // verify response from Asset + expect(response.status).toBe(200); + expect(await response.text()).toBe("

Hello Workers + Assets

"); - // verify no response from User Worker - response = await fetch(`${url}/hey`); - expect(response.status).toBe(404); - }); - }); + // verify no response from User Worker + response = await fetch(`${url}/hey`); + expect(response.status).toBe(404); + }); + } + ); }); diff --git a/packages/wrangler/e2e/helpers/normalize.ts b/packages/wrangler/e2e/helpers/normalize.ts index 6c0f1bffbe53..429afefad25c 100644 --- a/packages/wrangler/e2e/helpers/normalize.ts +++ b/packages/wrangler/e2e/helpers/normalize.ts @@ -11,6 +11,7 @@ export function normalizeOutput( removeWorkersDev, removeWorkerPreviewUrl, removeUUID, + removeBinding, normalizeErrorMarkers, replaceByte, stripTrailingWhitespace, @@ -62,12 +63,19 @@ function removeTimestamp(str: string) { .replace(/\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+?Z/g, "TIMESTAMP") .replace(/\d\d:\d\d:\d\d/g, "TIMESTAMP"); } + function removeUUID(str: string) { return str.replace( /\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/g, "00000000-0000-0000-0000-000000000000" ); } +function removeBinding(str: string) { + return str.replace( + /\w{8}_\w{4}_\w{4}_\w{4}_\w{12}/g, + "00000000_0000_0000_0000_000000000000" + ); +} /** * Remove the Wrangler version/update check header @@ -95,7 +103,7 @@ function normalizeErrorMarkers(str: string): string { * * Use this in snapshot tests to be resilient to file-system differences. */ -export function normalizeSlashes(str: string): string { +function normalizeSlashes(str: string): string { return str.replace(/\\/g, "/"); } @@ -104,7 +112,7 @@ export function normalizeSlashes(str: string): string { * * Use this in snapshot tests to be resilient to slight changes in timing of processing. */ -export function stripTimings(stdout: string): string { +function stripTimings(stdout: string): string { return stdout .replace(/\(\d+\.\d+ sec\)/g, "(TIMINGS)") .replace(/\d+ ms/g, "(TIMINGS)"); @@ -115,7 +123,7 @@ export function stripTimings(stdout: string): string { * * Use this in snapshot tests to be resilient to slight changes in timing of processing. */ -export function npmStripTimings(stdout: string): string { +function npmStripTimings(stdout: string): string { return stdout .replace( /added \d+ packages, and audited \d+ packages in [\dms]+/, @@ -127,7 +135,7 @@ export function npmStripTimings(stdout: string): string { ); } -export function stripTrailingWhitespace(str: string): string { +function stripTrailingWhitespace(str: string): string { return str.replace(/[^\S\n]+\n/g, "\n"); } @@ -142,14 +150,14 @@ function replaceByte(stdout: string): string { /** * Temp directories are created with random names, so we replace all comments temp dirs in them */ -export function normalizeTempDirs(stdout: string): string { +function normalizeTempDirs(stdout: string): string { return stdout.replaceAll(/\/\/.+\/wrangler-smoke-.+/g, "//tmpdir"); } /** * Debug log files are created with a timestamp, so we replace the debug log filepath timestamp with */ -export function normalizeDebugLogFilepath(stdout: string): string { +function normalizeDebugLogFilepath(stdout: string): string { return stdout .replace(/🪵 {2}Writing logs to ".+\.log"/, '🪵 Writing logs to ""') .replace( @@ -161,7 +169,7 @@ export function normalizeDebugLogFilepath(stdout: string): string { /** * Squash the one or more local network bindings from `$ wrangler dev` */ -export function removeLocalPort(stdout: string): string { +function removeLocalPort(stdout: string): string { return stdout.replace( /\[wrangler:inf\] Ready on (https?):\/\/(.+):\d{4,5}/, "[wrangler:inf] Ready on $1://$2:" diff --git a/packages/wrangler/e2e/pages-dev.test.ts b/packages/wrangler/e2e/pages-dev.test.ts index 6e0b634082ac..892d4a4c4a8d 100644 --- a/packages/wrangler/e2e/pages-dev.test.ts +++ b/packages/wrangler/e2e/pages-dev.test.ts @@ -7,10 +7,7 @@ import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test"; import { fetchText } from "./helpers/fetch-text"; import { normalizeOutput } from "./helpers/normalize"; -describe.each([ - { cmd: "wrangler pages dev --no-x-dev-env" }, - { cmd: "wrangler pages dev --x-dev-env" }, -])("Pages $cmd", ({ cmd }) => { +describe.each([{ cmd: "wrangler pages dev" }])("Pages $cmd", ({ cmd }) => { it("should warn if no [--compatibility_date] command line arg was specified", async () => { const helper = new WranglerE2ETestHelper(); await helper.seed({ diff --git a/packages/wrangler/e2e/r2.test.ts b/packages/wrangler/e2e/r2.test.ts index 3529b3061d64..94e5a84565a2 100644 --- a/packages/wrangler/e2e/r2.test.ts +++ b/packages/wrangler/e2e/r2.test.ts @@ -21,7 +21,11 @@ describe("r2", () => { expect(normalize(output.stdout)).toMatchInlineSnapshot(` "Creating bucket 'tmp-e2e-r2-00000000-0000-0000-0000-000000000000'... - ✅ Created bucket 'tmp-e2e-r2-00000000-0000-0000-0000-000000000000' with default storage class of Standard." + ✅ Created bucket 'tmp-e2e-r2-00000000-0000-0000-0000-000000000000' with default storage class of Standard. + Configure your Worker to write objects to this bucket: + [[r2_buckets]] + bucket_name = "tmp-e2e-r2-00000000-0000-0000-0000-000000000000" + binding = "tmp_e2e_r2_00000000_0000_0000_0000_000000000000"" `); }); diff --git a/packages/wrangler/package.json b/packages/wrangler/package.json index cb0d9eddd24b..6f665dcae218 100644 --- a/packages/wrangler/package.json +++ b/packages/wrangler/package.json @@ -1,6 +1,6 @@ { "name": "wrangler", - "version": "3.85.0", + "version": "3.86.1", "description": "Command-line interface for all things Cloudflare Workers", "keywords": [ "wrangler", @@ -74,7 +74,7 @@ "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "blake3-wasm": "^2.1.5", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "date-fns": "^4.1.0", "esbuild": "0.17.19", "itty-time": "^1.0.6", @@ -111,9 +111,7 @@ "@types/mime": "^3.0.4", "@types/minimatch": "^5.1.2", "@types/prompts": "^2.0.14", - "@types/react": "^18.3.3", "@types/resolve": "^1.20.6", - "@types/serve-static": "^1.13.10", "@types/shell-quote": "^1.7.2", "@types/signal-exit": "^3.0.1", "@types/supports-color": "^8.1.1", @@ -124,7 +122,6 @@ "body-parser": "^1.20.0", "chalk": "^5.2.0", "cli-table3": "^0.6.3", - "clipboardy": "^3.0.0", "cmd-shim": "^4.1.0", "command-exists": "^1.2.9", "concurrently": "^8.2.2", @@ -138,10 +135,6 @@ "http-terminator": "^3.2.0", "https-proxy-agent": "7.0.2", "ignore": "^5.2.0", - "ink": "^3.2.0", - "ink-select-input": "^4.2.1", - "ink-spinner": "^4.0.3", - "ink-table": "^3.0.0", "is-ci": "^3.0.1", "javascript-time-ago": "^2.5.4", "md5-file": "5.0.0", @@ -154,13 +147,8 @@ "patch-console": "^1.0.0", "pretty-bytes": "^6.0.0", "prompts": "^2.4.2", - "ps-list": "^8.1.1", - "react": "^18.3.1", - "react-error-boundary": "^3.1.4", "semiver": "^1.1.0", - "serve-static": "^1.15.0", "shell-quote": "^1.8.1", - "shellac": "^0.8.0", "signal-exit": "^3.0.7", "strip-ansi": "^7.1.0", "supports-color": "^9.2.2", @@ -173,8 +161,7 @@ "vitest-websocket-mock": "^0.4.0", "ws": "^8.18.0", "xdg-app-paths": "^8.3.0", - "yargs": "^17.7.2", - "yoga-layout": "file:../../vendor/yoga-layout-2.0.0-beta.1.tgz" + "yargs": "^17.7.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20241106.0" diff --git a/packages/wrangler/scripts/bundle.ts b/packages/wrangler/scripts/bundle.ts index b94d4ebce391..9fbe71d94700 100644 --- a/packages/wrangler/scripts/bundle.ts +++ b/packages/wrangler/scripts/bundle.ts @@ -1,4 +1,3 @@ -import fs from "node:fs/promises"; import path from "node:path"; import * as esbuild from "esbuild"; import { EXTERNAL_DEPENDENCIES } from "./deps"; @@ -67,18 +66,6 @@ async function buildMain(flags: BuildFlags = {}) { } else { await esbuild.build(options); } - - // Copy `yoga-layout` `.wasm` file - const yogaLayoutEntrypoint = require.resolve("yoga-layout"); - const wasmSrc = path.resolve( - yogaLayoutEntrypoint, - "..", - "..", - "build", - "wasm-sync.wasm" - ); - const wasmDst = path.resolve(outdir, "wasm-sync.wasm"); - await fs.copyFile(wasmSrc, wasmDst); } const workersContexts = new Map(); diff --git a/packages/wrangler/src/__tests__/api-devregistry.test.ts b/packages/wrangler/src/__tests__/api-devregistry.test.ts deleted file mode 100644 index f0e7e7430f51..000000000000 --- a/packages/wrangler/src/__tests__/api-devregistry.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { fetch } from "undici"; -import { vi } from "vitest"; -import { unstable_dev } from "../api"; -import { mockConsoleMethods } from "./helpers/mock-console"; - -vi.unmock("child_process"); -vi.unmock("undici"); - -// We need this outside the describe block to make sure the console spies are not -// torn down before the workers. -const std = mockConsoleMethods(); - -/** - * a huge caveat to how testing multi-worker scripts works: - * you can't shutdown the first worker you spun up, or it'll kill the devRegistry - */ -describe("multi-worker testing", () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let childWorker: any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let parentWorker: any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const workers: any[] = []; - - beforeEach(async () => { - childWorker = await unstable_dev( - "src/__tests__/helpers/worker-scripts/hello-world-worker.js", - { - config: "src/__tests__/helpers/worker-scripts/child-wrangler.toml", - ip: "127.0.0.1", - experimental: { - disableExperimentalWarning: true, - }, - } - ); - workers.push(childWorker); - - parentWorker = await unstable_dev( - "src/__tests__/helpers/worker-scripts/parent-worker.js", - { - config: "src/__tests__/helpers/worker-scripts/parent-wrangler.toml", - ip: "127.0.0.1", - experimental: { - disableExperimentalWarning: true, - }, - } - ); - workers.push(parentWorker); - }); - - afterEach(async () => { - for (const worker of workers) { - await worker.stop(); - } - }); - - it("parentWorker and childWorker should be added devRegistry", async () => { - const resp = await fetch("http://127.0.0.1:6284/workers"); - if (resp) { - const parsedResp = (await resp.json()) as { - parent: unknown; - child: unknown; - }; - expect(parsedResp.parent).toBeTruthy(); - expect(parsedResp.child).toBeTruthy(); - } - }); - - it("childWorker should return Hello World itself", async () => { - const resp = await childWorker.fetch(); - if (resp) { - const text = await resp.text(); - expect(text).toMatchInlineSnapshot(`"Hello World!"`); - } - }); - - it("parentWorker should return Hello World by invoking the child worker", async () => { - const resp = await parentWorker.fetch(); - if (resp) { - const parsedResp = await resp.text(); - expect(parsedResp).toEqual("Parent worker sees: Hello World!"); - } - }); - - it("should be able to stop and start the server with no warning logs", async () => { - async function startWorker() { - const worker = await unstable_dev( - "src/__tests__/helpers/worker-scripts/hello-world-worker.js", - { - // We need the wrangler.toml config to specify a Worker name - // otherwise unstable_dev will not register the worker with the DevRegistry - config: "src/__tests__/helpers/worker-scripts/child-wrangler.toml", - // We need debug logs because this is where the message is written if registering the worker fails. - logLevel: "debug", - ip: "127.0.0.1", - experimental: { - disableExperimentalWarning: true, - }, - } - ); - - workers.push(worker); - - return worker; - } - - let worker = await startWorker(); - - // Stop the worker and start it again - await worker.stop(); - await new Promise((r) => setTimeout(r, 2000)); - - worker = await startWorker(); - - const resp = await worker.fetch(); - expect(resp).not.toBe(undefined); - - await vi.waitFor(() => - /\[wrangler.*:inf].+GET.+\/.+200.+OK/.test(std.debug) - ); - - expect(std.debug).not.toMatch( - /Failed to register worker in local service registry/ - ); - }, 10000); -}); diff --git a/packages/wrangler/src/__tests__/deploy.test.ts b/packages/wrangler/src/__tests__/deploy.test.ts index 2d96ce3dcef1..29e38bb9fa40 100644 --- a/packages/wrangler/src/__tests__/deploy.test.ts +++ b/packages/wrangler/src/__tests__/deploy.test.ts @@ -29,7 +29,11 @@ import { mockOAuthFlow, } from "./helpers/mock-oauth-flow"; import { mockUploadWorkerRequest } from "./helpers/mock-upload-worker"; -import { mockSubDomainRequest } from "./helpers/mock-workers-subdomain"; +import { + mockGetWorkerSubdomain, + mockSubDomainRequest, + mockUpdateWorkerSubdomain, +} from "./helpers/mock-workers-subdomain"; import { createFetchResult, msw, @@ -94,9 +98,9 @@ describe("deploy", () => { routes: ["example.com/some-route/*"], workers_dev: true, }); - mockSubDomainRequest(); mockUploadWorkerRequest(); - mockUpdateWorkerRequest({ enabled: false }); + mockSubDomainRequest(); + mockGetWorkerSubdomain({ enabled: true }); mockPublishRoutesRequest({ routes: ["example.com/some-route/*"] }); await runWrangler("deploy ./index.js"); @@ -150,9 +154,10 @@ describe("deploy", () => { scriptName: "test-name", script: { id: "test-name", tag: "abc123" }, }); - mockSubDomainRequest(); mockUploadWorkerRequest(); - mockUpdateWorkerRequest({ enabled: false }); + mockSubDomainRequest(); + mockGetWorkerSubdomain({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: true }); mockPublishRoutesRequest({ routes: ["example.com/some-route/*"] }); await runWrangler("deploy ./index.js"); @@ -995,7 +1000,7 @@ describe("deploy", () => { routes: ["example.com/some-route/*"], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockPublishRoutesRequest({ routes: ["example.com/some-route/*"] }); await runWrangler("deploy ./index"); @@ -1006,7 +1011,7 @@ describe("deploy", () => { route: "", }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockSubDomainRequest(); mockPublishRoutesRequest({ routes: [] }); @@ -1045,7 +1050,7 @@ describe("deploy", () => { ], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockPublishRoutesRequest({ routes: [ @@ -1091,8 +1096,8 @@ describe("deploy", () => { ], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockGetZones("owned-zone.com", [{ id: "owned-zone-id-1" }]); mockGetWorkerRoutes("owned-zone-id-1"); mockPublishRoutesRequest({ @@ -1131,8 +1136,8 @@ describe("deploy", () => { ], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockGetZones("owned-zone.com", [{ id: "owned-zone-id-1" }]); mockGetWorkerRoutes("owned-zone-id-1"); mockPublishRoutesRequest({ @@ -1179,7 +1184,7 @@ describe("deploy", () => { }); mockSubDomainRequest(); writeWorkerSource(); - mockUpdateWorkerRequest({ + mockUpdateWorkerSubdomain({ enabled: false, env: "staging", legacyEnv: false, @@ -1240,7 +1245,11 @@ describe("deploy", () => { }, }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false, legacyEnv: true, env: "dev" }); + mockUpdateWorkerSubdomain({ + enabled: false, + legacyEnv: true, + env: "dev", + }); mockUploadWorkerRequest({ expectedType: "esm", legacyEnv: true, @@ -1264,7 +1273,7 @@ describe("deploy", () => { }, }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false, env: "dev" }); + mockUpdateWorkerSubdomain({ enabled: false, env: "dev" }); mockUploadWorkerRequest({ expectedType: "esm", env: "dev", @@ -1281,7 +1290,7 @@ describe("deploy", () => { routes: ["example.com/some-route/*"], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); // Simulate the bulk-routes API failing with a not authorized error. mockUnauthorizedPublishRoutesRequest(); @@ -1333,7 +1342,7 @@ describe("deploy", () => { legacy_env: false, }); writeWorkerSource(); - mockUpdateWorkerRequest({ env: "staging", enabled: false }); + mockUpdateWorkerSubdomain({ env: "staging", enabled: false }); mockUploadWorkerRequest({ env: "staging", expectedType: "esm" }); // Simulate the bulk-routes API failing with a not authorized error. mockUnauthorizedPublishRoutesRequest({ env: "staging" }); @@ -1362,7 +1371,7 @@ describe("deploy", () => { routes: [{ pattern: "api.example.com", custom_domain: true }], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockCustomDomainsChangesetRequest({}); mockPublishCustomDomainsRequest({ @@ -1382,7 +1391,7 @@ describe("deploy", () => { routes: [{ pattern: "api.example.com", custom_domain: true }], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockCustomDomainsChangesetRequest({ originConflicts: [ @@ -1427,7 +1436,7 @@ Update them to point to this script instead?`, routes: [{ pattern: "api.example.com", custom_domain: true }], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockCustomDomainsChangesetRequest({ dnsRecordConflicts: [ @@ -1464,7 +1473,7 @@ Update them to point to this script instead?`, routes: [{ pattern: "api.example.com", custom_domain: true }], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockCustomDomainsChangesetRequest({ originConflicts: [ @@ -1556,7 +1565,7 @@ Update them to point to this script instead?`, routes: [{ pattern: "api.example.com", custom_domain: true }], }); writeWorkerSource(); - mockUpdateWorkerRequest({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: false }); mockUploadWorkerRequest({ expectedType: "esm" }); mockCustomDomainsChangesetRequest({ originConflicts: [ @@ -4352,31 +4361,6 @@ addEventListener('fetch', event => {});` ); }); - it("should error if --assets and config.tail_consumers are used together", async () => { - writeWranglerToml({ - tail_consumers: [{ service: "" }], - }); - fs.mkdirSync("public"); - await expect( - runWrangler("deploy --assets public") - ).rejects.toThrowErrorMatchingInlineSnapshot( - `[Error: Cannot use assets and tail consumers in the same Worker. Tail Workers are not yet supported for Workers with assets.]` - ); - }); - - it("should error if config.assets and config.tail_consumers are used together", async () => { - writeWranglerToml({ - assets: { directory: "./public" }, - tail_consumers: [{ service: "" }], - }); - fs.mkdirSync("public"); - await expect( - runWrangler("deploy") - ).rejects.toThrowErrorMatchingInlineSnapshot( - `[Error: Cannot use assets and tail consumers in the same Worker. Tail Workers are not yet supported for Workers with assets.]` - ); - }); - it("should error if directory specified by flag --assets does not exist", async () => { await expect(runWrangler("deploy --assets abc")).rejects.toThrow( new RegExp( @@ -5001,7 +4985,9 @@ addEventListener('fetch', event => {});` writeWranglerToml(); writeWorkerSource(); mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockSubDomainRequest(); + mockUpdateWorkerSubdomain({ enabled: true }); await runWrangler("deploy ./index"); @@ -5021,9 +5007,10 @@ addEventListener('fetch', event => {});` workers_dev: true, }); writeWorkerSource(); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true }); + mockGetWorkerSubdomain({ enabled: false }); + mockUpdateWorkerSubdomain({ enabled: true }); await runWrangler("deploy ./index"); @@ -5043,7 +5030,8 @@ addEventListener('fetch', event => {});` workers_dev: true, }); writeWorkerSource(); - mockUploadWorkerRequest({ available_on_subdomain: true }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: true }); mockSubDomainRequest(); await runWrangler("deploy ./index"); @@ -5065,7 +5053,8 @@ addEventListener('fetch', event => {});` }); writeWorkerSource(); mockUploadWorkerRequest(); - mockUpdateWorkerRequest({ enabled: false }); + mockGetWorkerSubdomain({ enabled: true }); + mockUpdateWorkerSubdomain({ enabled: false }); await runWrangler("deploy ./index"); @@ -5084,8 +5073,8 @@ addEventListener('fetch', event => {});` workers_dev: false, }); writeWorkerSource(); - mockSubDomainRequest("test-sub-domain", false); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); // note the lack of a mock for the subdomain disable request @@ -5114,7 +5103,8 @@ addEventListener('fetch', event => {});` env: "dev", useOldUploadApi: true, }); - mockUpdateWorkerRequest({ enabled: false, env: "dev" }); + mockGetWorkerSubdomain({ enabled: true, env: "dev" }); + mockUpdateWorkerSubdomain({ enabled: false, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5141,7 +5131,8 @@ addEventListener('fetch', event => {});` mockUploadWorkerRequest({ env: "dev", }); - mockUpdateWorkerRequest({ enabled: false, env: "dev" }); + mockGetWorkerSubdomain({ enabled: true, env: "dev" }); + mockUpdateWorkerSubdomain({ enabled: false, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5168,8 +5159,9 @@ addEventListener('fetch', event => {});` env: "dev", useOldUploadApi: true, }); + mockGetWorkerSubdomain({ enabled: false, env: "dev" }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true, env: "dev" }); + mockUpdateWorkerSubdomain({ enabled: true, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5198,8 +5190,9 @@ addEventListener('fetch', event => {});` env: "dev", useOldUploadApi: true, }); + mockGetWorkerSubdomain({ enabled: false, env: "dev" }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true, env: "dev" }); + mockUpdateWorkerSubdomain({ enabled: true, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5230,7 +5223,7 @@ addEventListener('fetch', event => {});` useOldUploadApi: true, }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true, env: "dev" }); + mockGetWorkerSubdomain({ enabled: true, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5263,8 +5256,8 @@ addEventListener('fetch', event => {});` expectedCompatibilityFlags: ["global_navigator"], useOldUploadApi: true, }); + mockGetWorkerSubdomain({ enabled: true, env: "dev" }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true, env: "dev" }); await runWrangler("deploy ./index --env dev --legacy-env false"); @@ -5296,8 +5289,8 @@ addEventListener('fetch', event => {});` expectedCompatibilityDate: "2022-01-14", expectedCompatibilityFlags: ["url_standard"], }); + mockGetWorkerSubdomain({ enabled: true, env: "dev" }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true, env: "dev" }); await runWrangler( "deploy ./index --env dev --legacy-env false --compatibility-date 2022-01-14 --compatibility-flags url_standard" @@ -5359,9 +5352,10 @@ addEventListener('fetch', event => {});` it("should enable the workers.dev domain if workers_dev is undefined and subdomain is not already available", async () => { writeWranglerToml(); writeWorkerSource(); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true }); + mockUpdateWorkerSubdomain({ enabled: true }); await runWrangler("deploy ./index"); @@ -5379,9 +5373,10 @@ addEventListener('fetch', event => {});` it("should enable the workers.dev domain if workers_dev is true and subdomain is not already available", async () => { writeWranglerToml({ workers_dev: true }); writeWorkerSource(); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockSubDomainRequest(); - mockUpdateWorkerRequest({ enabled: true }); + mockUpdateWorkerSubdomain({ enabled: true }); await runWrangler("deploy ./index"); @@ -5399,7 +5394,8 @@ addEventListener('fetch', event => {});` it("should fail to deploy to the workers.dev domain if email is unverified", async () => { writeWranglerToml({ workers_dev: true }); writeWorkerSource(); - mockUploadWorkerRequest({ available_on_subdomain: false }); + mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockSubDomainRequest(); msw.use( http.post( @@ -5435,6 +5431,7 @@ addEventListener('fetch', event => {});` }); writeWorkerSource(); mockUploadWorkerRequest(); + mockGetWorkerSubdomain({ enabled: false }); mockSubDomainRequest("does-not-exist", false); mockConfirm({ @@ -5454,11 +5451,11 @@ addEventListener('fetch', event => {});` routes: ["http://example.com/*"], }); writeWorkerSource(); - mockSubDomainRequest(); mockUploadWorkerRequest(); - mockUpdateWorkerRequest({ - enabled: false, - }); + mockGetWorkerSubdomain({ enabled: false }); + // no set-subdomain call + mockGetZones("example.com", [{ id: "example-id" }]); + mockGetWorkerRoutes("example-id"); mockPublishRoutesRequest({ routes: ["http://example.com/*"] }); await runWrangler("deploy index.js"); @@ -5484,13 +5481,14 @@ addEventListener('fetch', event => {});` }, }); writeWorkerSource(); - mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockGetZones("production.example.com", [{ id: "example-id" }]); + mockGetWorkerRoutes("example-id"); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -5521,11 +5519,13 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockGetZones("production.example.com", [{ id: "example-id" }]); + mockGetWorkerRoutes("example-id"); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -5553,9 +5553,12 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest(); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, }); + mockUpdateWorkerSubdomain({ + enabled: true, + }); mockPublishRoutesRequest({ routes: ["http://example.com/*"], }); @@ -5586,11 +5589,16 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockUpdateWorkerSubdomain({ + enabled: true, + env: "production", + legacyEnv: true, + }); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -5623,11 +5631,16 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockUpdateWorkerSubdomain({ + enabled: true, + env: "production", + legacyEnv: true, + }); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -5660,11 +5673,13 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockGetZones("production.example.com", [{ id: "example-id" }]); + mockGetWorkerRoutes("example-id"); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -5696,11 +5711,13 @@ addEventListener('fetch', event => {});` writeWorkerSource(); mockSubDomainRequest(); mockUploadWorkerRequest({ env: "production", legacyEnv: true }); - mockUpdateWorkerRequest({ + mockGetWorkerSubdomain({ enabled: false, env: "production", legacyEnv: true, }); + mockGetZones("production.example.com", [{ id: "example-id" }]); + mockGetWorkerRoutes("example-id"); mockPublishRoutesRequest({ routes: ["http://production.example.com/*"], env: "production", @@ -11520,40 +11537,6 @@ function mockLastDeploymentRequest() { msw.use(...mswSuccessDeploymentScriptMetadata); } -/** Create a mock handler to toggle a