From 1a689615aa0829bf3a85fb943bffa935507e1ce7 Mon Sep 17 00:00:00 2001 From: Willie Chalmers III Date: Tue, 29 Sep 2026 20:02:14 -0700 Subject: [PATCH 1/2] chore(tooling): make cf the default in web templates Give new Astro and Vite repositories one cf package for built assets. Preserve preview URLs and route behavior without a second Wrangler deployment target. Pin patched transitive dependencies for the current toolchain. Co-authored-by: Codex --- docs/how-to/create-a-repository.md | 2 +- docs/reference/release-0-6-1.md | 14 ++ examples/basic/.claude/settings.json | 2 +- examples/basic/package.json | 4 +- examples/basic/packages/example/package.json | 6 +- examples/basic/pnpm-workspace.yaml | 3 + examples/with-astro/.claude/settings.json | 2 +- examples/with-astro/.gitignore | 1 + examples/with-astro/README.md | 5 +- .../apps/deploy/cloudflare.config.ts | 16 ++ .../with-astro/apps/deploy/eslint.config.js | 3 + examples/with-astro/apps/deploy/package.json | 19 ++ examples/with-astro/apps/deploy/tsconfig.json | 4 + .../with-astro/apps/deploy/wrangler.config.ts | 8 + examples/with-astro/apps/site/package.json | 8 +- examples/with-astro/apps/site/wrangler.jsonc | 14 -- .../docs/development/reference/glossary.md | 4 +- examples/with-astro/package.json | 4 +- examples/with-astro/pnpm-workspace.yaml | 3 + .../with-vite-react/.claude/settings.json | 2 +- examples/with-vite-react/.gitignore | 1 + examples/with-vite-react/README.md | 12 +- .../with-vite-react/apps/app/package.json | 8 +- .../with-vite-react/apps/app/wrangler.jsonc | 14 -- .../apps/deploy/cloudflare.config.ts | 16 ++ .../apps/deploy/eslint.config.js | 3 + .../with-vite-react/apps/deploy/package.json | 19 ++ .../with-vite-react/apps/deploy/tsconfig.json | 4 + .../apps/deploy/wrangler.config.ts | 8 + .../docs/development/reference/glossary.md | 4 +- examples/with-vite-react/package.json | 4 +- examples/with-vite-react/pnpm-workspace.yaml | 3 + package.json | 3 +- packages/cli/package.json | 2 +- packages/eslint-config/package.json | 2 +- packages/playwright-config/package.json | 2 +- packages/prettier-config/package.json | 2 +- packages/typescript-config/package.json | 2 +- packages/vitest-config/package.json | 2 +- packages/web-platform/package.json | 2 +- pnpm-lock.yaml | 169 ++++++++++++++++-- pnpm-workspace.yaml | 3 + tests/example.test.mjs | 2 +- tests/web-platform.test.mjs | 15 +- 44 files changed, 337 insertions(+), 89 deletions(-) create mode 100644 docs/reference/release-0-6-1.md create mode 100644 examples/with-astro/apps/deploy/cloudflare.config.ts create mode 100644 examples/with-astro/apps/deploy/eslint.config.js create mode 100644 examples/with-astro/apps/deploy/package.json create mode 100644 examples/with-astro/apps/deploy/tsconfig.json create mode 100644 examples/with-astro/apps/deploy/wrangler.config.ts delete mode 100644 examples/with-astro/apps/site/wrangler.jsonc delete mode 100644 examples/with-vite-react/apps/app/wrangler.jsonc create mode 100644 examples/with-vite-react/apps/deploy/cloudflare.config.ts create mode 100644 examples/with-vite-react/apps/deploy/eslint.config.js create mode 100644 examples/with-vite-react/apps/deploy/package.json create mode 100644 examples/with-vite-react/apps/deploy/tsconfig.json create mode 100644 examples/with-vite-react/apps/deploy/wrangler.config.ts diff --git a/docs/how-to/create-a-repository.md b/docs/how-to/create-a-repository.md index b56bbf4..129f346 100644 --- a/docs/how-to/create-a-repository.md +++ b/docs/how-to/create-a-repository.md @@ -55,7 +55,7 @@ install from the versioned snapshot under `.lvbt/web-platform`, so no registry l - Rename the root package in `package.json`. - Rename `packages/example`, `apps/site`, or `apps/app` to your first real package or app, or scaffold one with `turbo gen workspace` and delete the sample. Deployable templates also need the - Worker name in `apps/*/wrangler.jsonc` and, for a site, `site` in `astro.config.ts`. + Worker name in `apps/deploy/cloudflare.config.ts` and, for a site, `site` in `astro.config.ts`. - Replace the scopes in `.lvbt/commit-scopes.txt` with this repository's boundaries. - `.github/workflows/ci.yml` runs a job named `Validate`. Keep that name: the organization ruleset requires it on every pull request. Add steps to the job. diff --git a/docs/reference/release-0-6-1.md b/docs/reference/release-0-6-1.md new file mode 100644 index 0000000..b0a8e43 --- /dev/null +++ b/docs/reference/release-0-6-1.md @@ -0,0 +1,14 @@ +# Repository tooling 0.6.1 + +The Astro and Vite templates now deploy through `cf` from a separate `apps/deploy` package. This +package reads the app's built static assets, preserving the existing Worker name, compatibility +date, preview URLs, observability, and missing-page behavior. New templates contain one deploy +target, so `lvbt deploy` cannot publish a second copy through Wrangler. + +`lvbt deploy` builds the app before invoking `cf deploy`. New repositories must provide +`CLOUDFLARE_ACCOUNT_ID` and an account-owned `CLOUDFLARE_API_TOKEN` in their production GitHub +environment. `cf` is still in beta; its Wrangler build adapter remains an explicit dependency of the +deploy package. + +The source and new templates pin patched `fast-uri` and both supported `undici` major lines to avoid +high-severity transitive advisories in the current toolchain. diff --git a/examples/basic/.claude/settings.json b/examples/basic/.claude/settings.json index 294578b..95b7427 100644 --- a/examples/basic/.claude/settings.json +++ b/examples/basic/.claude/settings.json @@ -4,7 +4,7 @@ "source": { "source": "github", "repo": "LasVegasForTransit/repository-tooling", - "ref": "v0.6.0" + "ref": "v0.6.1" } } }, diff --git a/examples/basic/package.json b/examples/basic/package.json index 9774548..0adfa24 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -21,8 +21,8 @@ "*": "prettier --write --ignore-unknown" }, "devDependencies": { - "@lasvegasfortransit/cli": "0.6.0", - "@lasvegasfortransit/prettier-config": "0.6.0", + "@lasvegasfortransit/cli": "0.6.1", + "@lasvegasfortransit/prettier-config": "0.6.1", "lint-staged": "catalog:", "markdownlint-cli2": "catalog:", "markdownlint-rule-relative-links": "catalog:", diff --git a/examples/basic/packages/example/package.json b/examples/basic/packages/example/package.json index a5682ee..c8b17de 100644 --- a/examples/basic/packages/example/package.json +++ b/examples/basic/packages/example/package.json @@ -16,9 +16,9 @@ "test": "vitest run" }, "devDependencies": { - "@lasvegasfortransit/eslint-config": "0.6.0", - "@lasvegasfortransit/typescript-config": "0.6.0", - "@lasvegasfortransit/vitest-config": "0.6.0", + "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/typescript-config": "0.6.1", + "@lasvegasfortransit/vitest-config": "0.6.1", "@types/node": "catalog:", "eslint": "catalog:", "typescript": "catalog:", diff --git a/examples/basic/pnpm-workspace.yaml b/examples/basic/pnpm-workspace.yaml index e94d737..6f270af 100644 --- a/examples/basic/pnpm-workspace.yaml +++ b/examples/basic/pnpm-workspace.yaml @@ -16,7 +16,10 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: + fast-uri: 3.1.7 sharp: 0.35.4 + 'undici@^7.0.0': 7.29.1 + 'undici@^8.0.0': 8.10.2 smol-toml: 1.8.0 svgo: 4.1.0 diff --git a/examples/with-astro/.claude/settings.json b/examples/with-astro/.claude/settings.json index 294578b..95b7427 100644 --- a/examples/with-astro/.claude/settings.json +++ b/examples/with-astro/.claude/settings.json @@ -4,7 +4,7 @@ "source": { "source": "github", "repo": "LasVegasForTransit/repository-tooling", - "ref": "v0.6.0" + "ref": "v0.6.1" } } }, diff --git a/examples/with-astro/.gitignore b/examples/with-astro/.gitignore index 4cf35a7..94646a7 100644 --- a/examples/with-astro/.gitignore +++ b/examples/with-astro/.gitignore @@ -7,6 +7,7 @@ blob-report/ **/playwright/.cache/ .turbo/ .wrangler/ +.cloudflare/ .env .env.* !.env.example diff --git a/examples/with-astro/README.md b/examples/with-astro/README.md index a787103..4bc99a9 100644 --- a/examples/with-astro/README.md +++ b/examples/with-astro/README.md @@ -15,7 +15,7 @@ pnpm check # the same check CI runs pnpm dev # the site at http://127.0.0.1:4321 ``` -Then rename the root package and the Worker in `apps/site/wrangler.jsonc`, set `site` in +Then rename the root package and the Worker in `apps/deploy/cloudflare.config.ts`, set `site` in `apps/site/astro.config.ts`, and replace the scopes in `.lvbt/commit-scopes.txt` with this repository's boundaries. @@ -23,9 +23,10 @@ repository's boundaries. - `apps/site` is the Astro site: pages under `src/pages`, layouts under `src/layouts`, Tailwind in `src/styles/global.css`, unit tests under `tests/`, end-to-end tests under `tests/e2e/` +- `apps/deploy` holds the `cf` Worker configuration and reads `apps/site/dist` after the site build - `packages/` for libraries the site shares with other apps -`pnpm run deploy` builds and deploys every app with a `cloudflare.config.ts` or Wrangler config; +`pnpm run deploy` builds the site and deploys the canonical `cf` project in `apps/deploy`; `.github/workflows/deploy.yml` does the same on every push to `main`. Lint, format, TypeScript, and test settings extend the `@lasvegasfortransit/*` packages from diff --git a/examples/with-astro/apps/deploy/cloudflare.config.ts b/examples/with-astro/apps/deploy/cloudflare.config.ts new file mode 100644 index 0000000..9be2e6e --- /dev/null +++ b/examples/with-astro/apps/deploy/cloudflare.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'cf/config'; + +// Set CLOUDFLARE_ACCOUNT_ID in the deploy environment before publishing. +export default defineConfig({ + worker: { + name: 'lvbt-site', + compatibilityDate: '2026-08-31', + previewUrls: true, + assets: { + notFoundHandling: '404-page', + }, + observability: { + enabled: true, + }, + }, +}); diff --git a/examples/with-astro/apps/deploy/eslint.config.js b/examples/with-astro/apps/deploy/eslint.config.js new file mode 100644 index 0000000..fe2b986 --- /dev/null +++ b/examples/with-astro/apps/deploy/eslint.config.js @@ -0,0 +1,3 @@ +import { config } from '@lasvegasfortransit/eslint-config/base'; + +export default config; diff --git a/examples/with-astro/apps/deploy/package.json b/examples/with-astro/apps/deploy/package.json new file mode 100644 index 0000000..47eb580 --- /dev/null +++ b/examples/with-astro/apps/deploy/package.json @@ -0,0 +1,19 @@ +{ + "name": "@lasvegasfortransit/deploy", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "lint": "eslint . --max-warnings 0", + "check-types": "tsc --noEmit", + "test": "node --test" + }, + "devDependencies": { + "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/typescript-config": "0.6.1", + "cf": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:", + "wrangler": "catalog:" + } +} diff --git a/examples/with-astro/apps/deploy/tsconfig.json b/examples/with-astro/apps/deploy/tsconfig.json new file mode 100644 index 0000000..424aa9e --- /dev/null +++ b/examples/with-astro/apps/deploy/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@lasvegasfortransit/typescript-config/base.json", + "include": ["*.config.ts"] +} diff --git a/examples/with-astro/apps/deploy/wrangler.config.ts b/examples/with-astro/apps/deploy/wrangler.config.ts new file mode 100644 index 0000000..2cb09ad --- /dev/null +++ b/examples/with-astro/apps/deploy/wrangler.config.ts @@ -0,0 +1,8 @@ +import { defineWranglerConfig } from 'wrangler/experimental-config'; + +export default defineWranglerConfig({ + types: { + generate: false, + }, + assetsDirectory: '../site/dist', +}); diff --git a/examples/with-astro/apps/site/package.json b/examples/with-astro/apps/site/package.json index 153e7bf..d896c56 100644 --- a/examples/with-astro/apps/site/package.json +++ b/examples/with-astro/apps/site/package.json @@ -21,10 +21,10 @@ }, "devDependencies": { "@astrojs/check": "catalog:", - "@lasvegasfortransit/eslint-config": "0.6.0", - "@lasvegasfortransit/playwright-config": "0.6.0", - "@lasvegasfortransit/typescript-config": "0.6.0", - "@lasvegasfortransit/vitest-config": "0.6.0", + "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/playwright-config": "0.6.1", + "@lasvegasfortransit/typescript-config": "0.6.1", + "@lasvegasfortransit/vitest-config": "0.6.1", "@playwright/test": "catalog:", "@types/node": "catalog:", "eslint": "catalog:", diff --git a/examples/with-astro/apps/site/wrangler.jsonc b/examples/with-astro/apps/site/wrangler.jsonc deleted file mode 100644 index a4aab15..0000000 --- a/examples/with-astro/apps/site/wrangler.jsonc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "./node_modules/wrangler/config-schema.json", - // The Worker name. Rename it before the first deploy. - "name": "lvbt-site", - "compatibility_date": "2026-08-31", - "preview_urls": true, - "assets": { - "directory": "./dist", - "not_found_handling": "404-page", - }, - "observability": { - "enabled": true, - }, -} diff --git a/examples/with-astro/docs/development/reference/glossary.md b/examples/with-astro/docs/development/reference/glossary.md index 55588ff..c3eaa61 100644 --- a/examples/with-astro/docs/development/reference/glossary.md +++ b/examples/with-astro/docs/development/reference/glossary.md @@ -51,7 +51,7 @@ request. The required status is named `Validate`. deploy this repository, with a fix printed for anything missing. **Platform manifest**: `platform.json`, next to an app's production -`wrangler.jsonc`, which lists everything the app needs in production: its database, bucket, bot -check, admin sign-in, email domain, secrets, and the values that must never be set there. +configuration, which lists everything the app needs in production: its database, bucket, bot check, +admin sign-in, email domain, secrets, and the values that must never be set there. `pnpm preflight --production` checks production against it, and `pnpm bootstrap --production` sets up what is missing. diff --git a/examples/with-astro/package.json b/examples/with-astro/package.json index 3819e56..07fe528 100644 --- a/examples/with-astro/package.json +++ b/examples/with-astro/package.json @@ -23,8 +23,8 @@ "*": "prettier --write --ignore-unknown" }, "devDependencies": { - "@lasvegasfortransit/cli": "0.6.0", - "@lasvegasfortransit/prettier-config": "0.6.0", + "@lasvegasfortransit/cli": "0.6.1", + "@lasvegasfortransit/prettier-config": "0.6.1", "lint-staged": "catalog:", "markdownlint-cli2": "catalog:", "markdownlint-rule-relative-links": "catalog:", diff --git a/examples/with-astro/pnpm-workspace.yaml b/examples/with-astro/pnpm-workspace.yaml index e94d737..6f270af 100644 --- a/examples/with-astro/pnpm-workspace.yaml +++ b/examples/with-astro/pnpm-workspace.yaml @@ -16,7 +16,10 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: + fast-uri: 3.1.7 sharp: 0.35.4 + 'undici@^7.0.0': 7.29.1 + 'undici@^8.0.0': 8.10.2 smol-toml: 1.8.0 svgo: 4.1.0 diff --git a/examples/with-vite-react/.claude/settings.json b/examples/with-vite-react/.claude/settings.json index 294578b..95b7427 100644 --- a/examples/with-vite-react/.claude/settings.json +++ b/examples/with-vite-react/.claude/settings.json @@ -4,7 +4,7 @@ "source": { "source": "github", "repo": "LasVegasForTransit/repository-tooling", - "ref": "v0.6.0" + "ref": "v0.6.1" } } }, diff --git a/examples/with-vite-react/.gitignore b/examples/with-vite-react/.gitignore index 65717d9..393f057 100644 --- a/examples/with-vite-react/.gitignore +++ b/examples/with-vite-react/.gitignore @@ -7,6 +7,7 @@ blob-report/ **/playwright/.cache/ .turbo/ .wrangler/ +.cloudflare/ .env .env.* !.env.example diff --git a/examples/with-vite-react/README.md b/examples/with-vite-react/README.md index a787103..42ad025 100644 --- a/examples/with-vite-react/README.md +++ b/examples/with-vite-react/README.md @@ -15,17 +15,17 @@ pnpm check # the same check CI runs pnpm dev # the site at http://127.0.0.1:4321 ``` -Then rename the root package and the Worker in `apps/site/wrangler.jsonc`, set `site` in -`apps/site/astro.config.ts`, and replace the scopes in `.lvbt/commit-scopes.txt` with this -repository's boundaries. +Then rename the root package and the Worker in `apps/deploy/cloudflare.config.ts`, and replace the +scopes in `.lvbt/commit-scopes.txt` with this repository's boundaries. ## Layout -- `apps/site` is the Astro site: pages under `src/pages`, layouts under `src/layouts`, Tailwind in - `src/styles/global.css`, unit tests under `tests/`, end-to-end tests under `tests/e2e/` +- `apps/app` is the Vite app: source under `src/`, unit tests under `tests/`, and end-to-end tests + under `tests/e2e/` +- `apps/deploy` holds the `cf` Worker configuration and reads `apps/app/dist` after the app build - `packages/` for libraries the site shares with other apps -`pnpm run deploy` builds and deploys every app with a `cloudflare.config.ts` or Wrangler config; +`pnpm run deploy` builds the app and deploys the canonical `cf` project in `apps/deploy`; `.github/workflows/deploy.yml` does the same on every push to `main`. Lint, format, TypeScript, and test settings extend the `@lasvegasfortransit/*` packages from diff --git a/examples/with-vite-react/apps/app/package.json b/examples/with-vite-react/apps/app/package.json index 6a301e1..ab8dd5c 100644 --- a/examples/with-vite-react/apps/app/package.json +++ b/examples/with-vite-react/apps/app/package.json @@ -17,10 +17,10 @@ "react-dom": "catalog:" }, "devDependencies": { - "@lasvegasfortransit/eslint-config": "0.6.0", - "@lasvegasfortransit/playwright-config": "0.6.0", - "@lasvegasfortransit/typescript-config": "0.6.0", - "@lasvegasfortransit/vitest-config": "0.6.0", + "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/playwright-config": "0.6.1", + "@lasvegasfortransit/typescript-config": "0.6.1", + "@lasvegasfortransit/vitest-config": "0.6.1", "@playwright/test": "catalog:", "@tailwindcss/vite": "catalog:", "@types/node": "catalog:", diff --git a/examples/with-vite-react/apps/app/wrangler.jsonc b/examples/with-vite-react/apps/app/wrangler.jsonc deleted file mode 100644 index 9c876a5..0000000 --- a/examples/with-vite-react/apps/app/wrangler.jsonc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "./node_modules/wrangler/config-schema.json", - // The Worker name. Rename it before the first deploy. - "name": "lvbt-app", - "compatibility_date": "2026-08-31", - "preview_urls": true, - "assets": { - "directory": "./dist", - "not_found_handling": "single-page-application", - }, - "observability": { - "enabled": true, - }, -} diff --git a/examples/with-vite-react/apps/deploy/cloudflare.config.ts b/examples/with-vite-react/apps/deploy/cloudflare.config.ts new file mode 100644 index 0000000..f5541d9 --- /dev/null +++ b/examples/with-vite-react/apps/deploy/cloudflare.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'cf/config'; + +// Set CLOUDFLARE_ACCOUNT_ID in the deploy environment before publishing. +export default defineConfig({ + worker: { + name: 'lvbt-app', + compatibilityDate: '2026-08-31', + previewUrls: true, + assets: { + notFoundHandling: 'single-page-application', + }, + observability: { + enabled: true, + }, + }, +}); diff --git a/examples/with-vite-react/apps/deploy/eslint.config.js b/examples/with-vite-react/apps/deploy/eslint.config.js new file mode 100644 index 0000000..fe2b986 --- /dev/null +++ b/examples/with-vite-react/apps/deploy/eslint.config.js @@ -0,0 +1,3 @@ +import { config } from '@lasvegasfortransit/eslint-config/base'; + +export default config; diff --git a/examples/with-vite-react/apps/deploy/package.json b/examples/with-vite-react/apps/deploy/package.json new file mode 100644 index 0000000..47eb580 --- /dev/null +++ b/examples/with-vite-react/apps/deploy/package.json @@ -0,0 +1,19 @@ +{ + "name": "@lasvegasfortransit/deploy", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "lint": "eslint . --max-warnings 0", + "check-types": "tsc --noEmit", + "test": "node --test" + }, + "devDependencies": { + "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/typescript-config": "0.6.1", + "cf": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:", + "wrangler": "catalog:" + } +} diff --git a/examples/with-vite-react/apps/deploy/tsconfig.json b/examples/with-vite-react/apps/deploy/tsconfig.json new file mode 100644 index 0000000..424aa9e --- /dev/null +++ b/examples/with-vite-react/apps/deploy/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@lasvegasfortransit/typescript-config/base.json", + "include": ["*.config.ts"] +} diff --git a/examples/with-vite-react/apps/deploy/wrangler.config.ts b/examples/with-vite-react/apps/deploy/wrangler.config.ts new file mode 100644 index 0000000..fa36cac --- /dev/null +++ b/examples/with-vite-react/apps/deploy/wrangler.config.ts @@ -0,0 +1,8 @@ +import { defineWranglerConfig } from 'wrangler/experimental-config'; + +export default defineWranglerConfig({ + types: { + generate: false, + }, + assetsDirectory: '../app/dist', +}); diff --git a/examples/with-vite-react/docs/development/reference/glossary.md b/examples/with-vite-react/docs/development/reference/glossary.md index 55588ff..c3eaa61 100644 --- a/examples/with-vite-react/docs/development/reference/glossary.md +++ b/examples/with-vite-react/docs/development/reference/glossary.md @@ -51,7 +51,7 @@ request. The required status is named `Validate`. deploy this repository, with a fix printed for anything missing. **Platform manifest**: `platform.json`, next to an app's production -`wrangler.jsonc`, which lists everything the app needs in production: its database, bucket, bot -check, admin sign-in, email domain, secrets, and the values that must never be set there. +configuration, which lists everything the app needs in production: its database, bucket, bot check, +admin sign-in, email domain, secrets, and the values that must never be set there. `pnpm preflight --production` checks production against it, and `pnpm bootstrap --production` sets up what is missing. diff --git a/examples/with-vite-react/package.json b/examples/with-vite-react/package.json index de29b0b..a4261bc 100644 --- a/examples/with-vite-react/package.json +++ b/examples/with-vite-react/package.json @@ -23,8 +23,8 @@ "*": "prettier --write --ignore-unknown" }, "devDependencies": { - "@lasvegasfortransit/cli": "0.6.0", - "@lasvegasfortransit/prettier-config": "0.6.0", + "@lasvegasfortransit/cli": "0.6.1", + "@lasvegasfortransit/prettier-config": "0.6.1", "lint-staged": "catalog:", "markdownlint-cli2": "catalog:", "markdownlint-rule-relative-links": "catalog:", diff --git a/examples/with-vite-react/pnpm-workspace.yaml b/examples/with-vite-react/pnpm-workspace.yaml index e94d737..6f270af 100644 --- a/examples/with-vite-react/pnpm-workspace.yaml +++ b/examples/with-vite-react/pnpm-workspace.yaml @@ -16,7 +16,10 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: + fast-uri: 3.1.7 sharp: 0.35.4 + 'undici@^7.0.0': 7.29.1 + 'undici@^8.0.0': 8.10.2 smol-toml: 1.8.0 svgo: 4.1.0 diff --git a/package.json b/package.json index 4fcbc04..1f9ae0e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "lvbt-repository-tooling", "private": true, - "version": "0.6.0", + "version": "0.6.1", "type": "module", "description": "Source of truth for the LVBT repository standard: the shared @lasvegasfortransit packages and the example repositories create-turbo copies.", "packageManager": "pnpm@11.25.0", @@ -39,6 +39,7 @@ "@types/react-dom": "catalog:", "@vitejs/plugin-react": "catalog:", "astro": "catalog:", + "cf": "catalog:", "eslint": "catalog:", "lint-staged": "catalog:", "markdownlint-cli2": "catalog:", diff --git a/packages/cli/package.json b/packages/cli/package.json index 497fb58..6c90379 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/cli", - "version": "0.6.0", + "version": "0.6.1", "description": "The lvbt command every LVBT repository runs for bootstrap, preflight, and deploy, plus the production platform setup, the shared git hooks, and the lvbt-contributions agent plugin.", "license": "MIT", "type": "module", diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index dbc81e9..bfb8e9a 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/eslint-config", - "version": "0.6.0", + "version": "0.6.1", "description": "The ESLint configurations every LVBT repository uses.", "license": "MIT", "type": "module", diff --git a/packages/playwright-config/package.json b/packages/playwright-config/package.json index ad22bff..f706fb5 100644 --- a/packages/playwright-config/package.json +++ b/packages/playwright-config/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/playwright-config", - "version": "0.6.0", + "version": "0.6.1", "description": "The Playwright configuration every LVBT repository spreads into its own: end-to-end tests under tests/e2e, desktop and mobile projects, traces on failure.", "license": "MIT", "type": "module", diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json index 284568f..d7a43ad 100644 --- a/packages/prettier-config/package.json +++ b/packages/prettier-config/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/prettier-config", - "version": "0.6.0", + "version": "0.6.1", "description": "The Prettier configuration every LVBT repository uses.", "license": "MIT", "type": "module", diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index ff21f71..e3747a2 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/typescript-config", - "version": "0.6.0", + "version": "0.6.1", "description": "TypeScript configurations every LVBT repository extends.", "license": "MIT", "repository": { diff --git a/packages/vitest-config/package.json b/packages/vitest-config/package.json index 5e7f867..ce83c81 100644 --- a/packages/vitest-config/package.json +++ b/packages/vitest-config/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/vitest-config", - "version": "0.6.0", + "version": "0.6.1", "description": "The Vitest configuration every LVBT repository spreads into its own.", "license": "MIT", "type": "module", diff --git a/packages/web-platform/package.json b/packages/web-platform/package.json index e03030d..31e77b3 100644 --- a/packages/web-platform/package.json +++ b/packages/web-platform/package.json @@ -1,6 +1,6 @@ { "name": "@lasvegasfortransit/web-platform", - "version": "0.6.0", + "version": "0.6.1", "description": "Provider-neutral deployment, provisioning, and validation primitives for LVBT web repositories.", "license": "MIT", "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db1789a..cb63fed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ catalogs: astro: specifier: 7.2.10 version: 7.2.10 + cf: + specifier: 1.0.0-beta.5 + version: 1.0.0-beta.5 eslint: specifier: 10.9.1 version: 10.9.1 @@ -80,7 +83,10 @@ catalogs: version: 4.141.0 overrides: + fast-uri: 3.1.7 sharp: 0.35.4 + undici@^7.0.0: 7.29.1 + undici@^8.0.0: 8.10.2 smol-toml: 1.8.0 svgo: 4.1.0 @@ -133,6 +139,9 @@ importers: astro: specifier: 'catalog:' version: 7.2.10(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0) + cf: + specifier: 'catalog:' + version: 1.0.0-beta.5(@types/node@24.13.3) eslint: specifier: 'catalog:' version: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) @@ -491,10 +500,23 @@ packages: resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} engines: {node: '>= 20.12.0'} + '@cloudflare/build-output-utils@0.8.2': + resolution: {integrity: sha512-DHKF7p5p1ZapZbh2GyF3mfBW7D45IKtcnwMdKnVZ72A/a2rfwd1kczBYFH+O4cHnNI7e9HRwTm+Z76IDZfxVLw==} + + '@cloudflare/codemods@0.2.1': + resolution: {integrity: sha512-nAoXTs5JPlQ8HeaTJQaxkvbJtGjXG19HoNx/W/Cz1d2PBETAt1Pdv4KqKqMw62DNq6Wfh4lwG2lJLvyn4X+Rhg==} + hasBin: true + + '@cloudflare/config@0.20.0': + resolution: {integrity: sha512-Dv/UDLkqsmvW95+CmM2nE55pdkLPWnJ63KDMjAFe/5KW1hc2SzJW4f8CUagqarivQugf5+oJMWYlHSmtA4KVlA==} + '@cloudflare/kv-asset-handler@0.5.0': resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} engines: {node: '>=22.0.0'} + '@cloudflare/runtime-types@0.1.4': + resolution: {integrity: sha512-Jp3Za6h0KybVoi/4D6La3HicW71L8nyS7AGf0WHpbKqCs17lLkCuTbOcAuUTraoib8+SR74L+AbqxwcDq3VhTw==} + '@cloudflare/unenv-preset@2.16.2': resolution: {integrity: sha512-JBP1+Z7ZSNG/d4mRP+y8VC5dka3tZVMLEZRvS+rzQ4DGV1EoxRFQckcJTTkXbHSQiTj0DtNI01Zwb/V2fX0mvQ==} peerDependencies: @@ -510,30 +532,60 @@ packages: cpu: [x64] os: [darwin] + '@cloudflare/workerd-darwin-64@1.20260926.1': + resolution: {integrity: sha512-VCIpwgJu5Dm1o+VHLclNOKIdpttEqss7oDHS5DYxgVoonM9Dxxxr1xCQvJbh6IXFuQ1DDrbm5krjte5NsTgX3Q==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + '@cloudflare/workerd-darwin-arm64@1.20260925.1': resolution: {integrity: sha512-b3BLoP9NkF6b2QOQFs8wFfOt9XSH3jVtacdGn9lcvkUCdPq7F6CfDlleHqyQEnDfZ32lH5jgMRTdaMHUPf/XbA==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] + '@cloudflare/workerd-darwin-arm64@1.20260926.1': + resolution: {integrity: sha512-oVuLXfCnr1Xu9sBMNYrEPcFZQNMcviNcacz9l+oqQiLHc5UrVp++lpKbsuWstCfh+/c39Pp37TVeaNBLA8+ReA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + '@cloudflare/workerd-linux-64@1.20260925.1': resolution: {integrity: sha512-LczXd6uEMqEmBxBJPFwplRIwKmUHqj5t8hilIWOtbX5i0TFp7/iMYBXbAiIhvZnev+8yiTyA7uWBBjDvfPh5Ug==} engines: {node: '>=16'} cpu: [x64] os: [linux] + '@cloudflare/workerd-linux-64@1.20260926.1': + resolution: {integrity: sha512-BjmiDvYBVBG5248gCHSZS3yONbcm3/3qKTu9RaQA8o7jQHJfXx9JnWbhkld2KsbXnRGEGHFwpLLidIpIGtQYUA==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + '@cloudflare/workerd-linux-arm64@1.20260925.1': resolution: {integrity: sha512-hziOugQbLuva85w8z9bGJbEtABKzSip653x0NgvxgP/Q3n1TpRqRyIJRBufbSUZRkJlfH2se2nQaTx2OU0TT3g==} engines: {node: '>=16'} cpu: [arm64] os: [linux] + '@cloudflare/workerd-linux-arm64@1.20260926.1': + resolution: {integrity: sha512-28bdfQDIFcpaKXMPisADy8BchpIsX+tEAhD+bhfEBXukFGFr8F3ouyiG3HzN3CqAh/OYvifJizzFZtptUPCy7w==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + '@cloudflare/workerd-windows-64@1.20260925.1': resolution: {integrity: sha512-mG0JYuF6HVCgXSsNeB5os8Vtdprk5jHPysviKNNMHJSLA3Q1djFjSmK4+pnQR/zOAgzNo0HJ+Tpcz+tZj1Q7fQ==} engines: {node: '>=16'} cpu: [x64] os: [win32] + '@cloudflare/workerd-windows-64@1.20260926.1': + resolution: {integrity: sha512-ehdL3ataKdEmlnW9oom6OZUR8n3XsTL/zl8+KGREpLi5sMSW0mek0PrF4wK9SX51f3Alnlu8tF8eKBg+mc3xFw==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1765,6 +1817,11 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + cf@1.0.0-beta.5: + resolution: {integrity: sha512-IKGKDAQNs8hbu7jOt3qSWKxDjmJTS+hcHCJ5B0IkF7gZ3RmEfMTUxZ0Fi7GRftjag04J127u8Nk8uppXx3OBZw==} + engines: {node: '>=22'} + hasBin: true + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -2057,8 +2114,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.6: - resolution: {integrity: sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==} + fast-uri@3.1.7: + resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -2610,10 +2667,17 @@ packages: resolution: {integrity: sha512-ly2ygNOfuouMiPcyTNEUW6f3+zgndfC45e1nQZ2LSciOSFfrih8V7ciaZ01I/64Ccp3F6fWraxh5VuHPsP3AAw==} engines: {node: '>=22.0.0'} + miniflare@5.20260926.0-alpha: + resolution: {integrity: sha512-m/M3rpLnaouw6QSoKzylfw6Z1dnOwRM48idnZ7kc5ivRqBXANFQ8XqKCyQ/V+xqQ9Rg1L99j4WkZGVU9uT4L2w==} + engines: {node: '>=22.0.0'} + minimatch@10.2.6: resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} + minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -3058,12 +3122,12 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - undici@7.29.0: - resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} + undici@7.29.1: + resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} engines: {node: '>=20.18.1'} - undici@8.10.1: - resolution: {integrity: sha512-YQ3WlbqjYMmNpdvDH64jAgLjxuAR9+649calDWhbshYaeQGO2bR4nI94ORJmwI3J9YhoKQnpyGOK+0zlWS5N5Q==} + undici@8.10.2: + resolution: {integrity: sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==} engines: {node: '>=22.19.0'} unenv@2.0.0-rc.24: @@ -3390,6 +3454,11 @@ packages: engines: {node: '>=16'} hasBin: true + workerd@1.20260926.1: + resolution: {integrity: sha512-YojhsWBuZwk3Jk9OC0QfTgVbLeQOD1tK1olC9ZXAUcmeip8z4NE/xtttpxCsuTvQBRqppvy7Tkac0kxPYMjIXA==} + engines: {node: '>=16'} + hasBin: true + wrangler@4.141.0: resolution: {integrity: sha512-8+LRZEcynBMfVYgO4N378z5XyuajaILt2IzsdWRLCHrRWz7mmGWv4igdVjqbRQMJtE0S5bSmyz0W2XpA6UM/ow==} engines: {node: '>=22.0.0'} @@ -3468,6 +3537,9 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zod@4.5.4: resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} @@ -3759,8 +3831,27 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 + '@cloudflare/build-output-utils@0.8.2': + dependencies: + '@cloudflare/config': 0.20.0 + + '@cloudflare/codemods@0.2.1': {} + + '@cloudflare/config@0.20.0': + dependencies: + zod: 4.4.3 + '@cloudflare/kv-asset-handler@0.5.0': {} + '@cloudflare/runtime-types@0.1.4(@types/node@24.13.3)': + dependencies: + miniflare: 5.20260926.0-alpha(@types/node@24.13.3) + workerd: 1.20260926.1 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + '@cloudflare/unenv-preset@2.16.2(unenv@2.0.0-rc.24)(workerd@1.20260925.1)': dependencies: unenv: 2.0.0-rc.24 @@ -3770,18 +3861,33 @@ snapshots: '@cloudflare/workerd-darwin-64@1.20260925.1': optional: true + '@cloudflare/workerd-darwin-64@1.20260926.1': + optional: true + '@cloudflare/workerd-darwin-arm64@1.20260925.1': optional: true + '@cloudflare/workerd-darwin-arm64@1.20260926.1': + optional: true + '@cloudflare/workerd-linux-64@1.20260925.1': optional: true + '@cloudflare/workerd-linux-64@1.20260926.1': + optional: true + '@cloudflare/workerd-linux-arm64@1.20260925.1': optional: true + '@cloudflare/workerd-linux-arm64@1.20260926.1': + optional: true + '@cloudflare/workerd-windows-64@1.20260925.1': optional: true + '@cloudflare/workerd-windows-64@1.20260926.1': + optional: true + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -4680,7 +4786,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.6 + fast-uri: 3.1.7 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -4834,6 +4940,20 @@ snapshots: ccount@2.0.1: {} + cf@1.0.0-beta.5(@types/node@24.13.3): + dependencies: + '@cloudflare/build-output-utils': 0.8.2 + '@cloudflare/codemods': 0.2.1 + '@cloudflare/config': 0.20.0 + '@cloudflare/runtime-types': 0.1.4(@types/node@24.13.3) + blake3-wasm: 2.1.5 + miniflare: 5.20260926.0-alpha(@types/node@24.13.3) + minisearch: 7.2.0 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + chai@6.2.2: {} character-entities-html4@2.1.0: {} @@ -5180,7 +5300,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.6: {} + fast-uri@3.1.7: {} fast-wrap-ansi@0.2.2: dependencies: @@ -5776,7 +5896,7 @@ snapshots: dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.35.4(@types/node@24.13.3) - undici: 7.29.0 + undici: 7.29.1 workerd: 1.20260925.1 ws: 8.21.0 youch: 4.1.0-beta.10 @@ -5785,10 +5905,25 @@ snapshots: - bufferutil - utf-8-validate + miniflare@5.20260926.0-alpha(@types/node@24.13.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + sharp: 0.35.4(@types/node@24.13.3) + undici: 7.29.1 + workerd: 1.20260926.1 + ws: 8.21.0 + youch: 4.1.0-beta.10 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + minimatch@10.2.6: dependencies: brace-expansion: 5.0.9 + minisearch@7.2.0: {} + mrmime@2.0.1: {} ms@2.1.3: {} @@ -6237,9 +6372,9 @@ snapshots: undici-types@7.18.2: {} - undici@7.29.0: {} + undici@7.29.1: {} - undici@8.10.1: {} + undici@8.10.2: {} unenv@2.0.0-rc.24: dependencies: @@ -6261,7 +6396,7 @@ snapshots: dependencies: css-tree: 3.2.1 ohash: 2.0.12 - undici: 8.10.1 + undici: 8.10.2 unist-util-is@6.0.1: dependencies: @@ -6490,6 +6625,14 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260925.1 '@cloudflare/workerd-windows-64': 1.20260925.1 + workerd@1.20260926.1: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20260926.1 + '@cloudflare/workerd-darwin-arm64': 1.20260926.1 + '@cloudflare/workerd-linux-64': 1.20260926.1 + '@cloudflare/workerd-linux-arm64': 1.20260926.1 + '@cloudflare/workerd-windows-64': 1.20260926.1 + wrangler@4.141.0(@types/node@24.13.3): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 @@ -6572,6 +6715,8 @@ snapshots: dependencies: zod: 4.5.4 + zod@4.4.3: {} + zod@4.5.4: {} zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9c4d163..51aee07 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,7 +15,10 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: + fast-uri: 3.1.7 sharp: 0.35.4 + 'undici@^7.0.0': 7.29.1 + 'undici@^8.0.0': 8.10.2 smol-toml: 1.8.0 svgo: 4.1.0 diff --git a/tests/example.test.mjs b/tests/example.test.mjs index 495dc36..c09803e 100644 --- a/tests/example.test.mjs +++ b/tests/example.test.mjs @@ -436,7 +436,7 @@ test('source and generated repositories pin audited transitive fixes', async () ); assert.match( workspace, - /^overrides:\n {2}sharp: 0\.35\.4\n {2}smol-toml: 1\.8\.0\n {2}svgo: 4\.1\.0$/m, + /^overrides:\n {2}fast-uri: 3\.1\.7\n {2}sharp: 0\.35\.4\n {2}'undici@\^7\.0\.0': 7\.29\.1\n {2}'undici@\^8\.0\.0': 8\.10\.2\n {2}smol-toml: 1\.8\.0\n {2}svgo: 4\.1\.0$/m, ); } }); diff --git a/tests/web-platform.test.mjs b/tests/web-platform.test.mjs index 04e309b..890792a 100644 --- a/tests/web-platform.test.mjs +++ b/tests/web-platform.test.mjs @@ -7,6 +7,7 @@ import path from 'node:path'; import { applyPreset, verifyPreset, fingerprint } from '../standards/web-platform.ts'; import { readCommit, readRelease } from '../standards/web-platform-source.ts'; +import { deployables } from '../packages/cli/src/lib/operate.mjs'; async function fixture(run) { const directory = await mkdtemp(path.join(os.tmpdir(), 'lvbt-preset-')); @@ -211,13 +212,13 @@ test('reads an unpublished preset only from an exact commit', () => assert.throws(() => readCommit(repository, 'main'), /full commit/i); })); -test('web profiles preserve immutable Worker version previews', async () => { - for (const file of [ - 'examples/with-astro/apps/site/wrangler.jsonc', - 'examples/with-vite-react/apps/app/wrangler.jsonc', - ]) { - const config = await readFile(path.join(new URL('..', import.meta.url).pathname, file), 'utf8'); - assert.match(config, /"preview_urls": true/); +test('web profiles deploy once through cf and preserve Worker version previews', async () => { + const root = new URL('..', import.meta.url).pathname; + for (const profile of ['with-astro', 'with-vite-react']) { + const example = path.join(root, 'examples', profile); + assert.deepEqual(await deployables(example), [{ directory: 'apps/deploy', tool: 'cf' }]); + const config = await readFile(path.join(example, 'apps/deploy/cloudflare.config.ts'), 'utf8'); + assert.match(config, /previewUrls: true/); } }); From 9f47d95bad2d52281bd2758de910069a0a33e75a Mon Sep 17 00:00:00 2001 From: Willie Chalmers III Date: Tue, 29 Sep 2026 22:05:48 -0700 Subject: [PATCH 2/2] chore(tooling): validate generated cf bundles Make generated Astro and Vite repositories build their app before the Cloudflare dry run, and test that dependency in the template task graph. Update release guidance and select patched transitive packages. Co-authored-by: Codex --- docs/reference/examples.md | 14 ++++++------- docs/reference/release-0-6-1.md | 6 +++--- examples/basic/pnpm-workspace.yaml | 3 ++- examples/with-astro/apps/deploy/package.json | 4 +++- .../docs/development/tutorials/start-here.md | 8 ++++---- examples/with-astro/pnpm-workspace.yaml | 3 ++- .../with-vite-react/apps/deploy/package.json | 4 +++- .../docs/development/tutorials/start-here.md | 8 ++++---- examples/with-vite-react/pnpm-workspace.yaml | 3 ++- pnpm-lock.yaml | 19 +++++++++--------- pnpm-workspace.yaml | 3 ++- tests/example.test.mjs | 4 ++-- tests/web-platform.test.mjs | 20 +++++++++++++++++++ 13 files changed, 64 insertions(+), 35 deletions(-) diff --git a/docs/reference/examples.md b/docs/reference/examples.md index aceade1..645fba1 100644 --- a/docs/reference/examples.md +++ b/docs/reference/examples.md @@ -45,13 +45,13 @@ files. `with-astro` and `with-vite-react` carry everything above, minus `packages/example`, plus: -| Path | Purpose | -| ------------------------------ | ---------------------------------------------------------------------------------------------------- | -| `apps/site` or `apps/app` | The application: source under `src/`, unit tests under `tests/`, end-to-end tests under `tests/e2e/` | -| `apps/*/wrangler.jsonc` | A static-assets Worker serving `dist/`; `pnpm run deploy` deploys every app that has one | -| `apps/*/playwright.config.ts` | Spreads `@lasvegasfortransit/playwright-config` and starts the app's `preview` server | -| `.github/workflows/deploy.yml` | Validates, then runs `pnpm run deploy` on every push to `main` with the Cloudflare secrets | -| root `preview` and `deploy` | `turbo run preview` and `lvbt deploy` | +| Path | Purpose | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `apps/site` or `apps/app` | The application: source under `src/`, unit tests under `tests/`, end-to-end tests under `tests/e2e/` | +| `apps/deploy/cloudflare.config.ts` | The `cf` Worker project, which serves the app's built static assets | +| `apps/*/playwright.config.ts` | Spreads `@lasvegasfortransit/playwright-config` and starts the app's `preview` server | +| `.github/workflows/deploy.yml` | Validates, then runs `pnpm run deploy` on every push to `main` with the Cloudflare secrets | +| root `preview` and `deploy` | `turbo run preview` and `lvbt deploy`; CI builds the app and dry-runs `cf deploy` | The Astro example also adds `prettier-plugin-astro` to its Prettier config and extends `@lasvegasfortransit/typescript-config/astro.json`; the React example extends `react-library.json` diff --git a/docs/reference/release-0-6-1.md b/docs/reference/release-0-6-1.md index b0a8e43..2563333 100644 --- a/docs/reference/release-0-6-1.md +++ b/docs/reference/release-0-6-1.md @@ -8,7 +8,7 @@ target, so `lvbt deploy` cannot publish a second copy through Wrangler. `lvbt deploy` builds the app before invoking `cf deploy`. New repositories must provide `CLOUDFLARE_ACCOUNT_ID` and an account-owned `CLOUDFLARE_API_TOKEN` in their production GitHub environment. `cf` is still in beta; its Wrangler build adapter remains an explicit dependency of the -deploy package. +deploy package. The required repository check builds the app and dry-runs its Cloudflare bundle. -The source and new templates pin patched `fast-uri` and both supported `undici` major lines to avoid -high-severity transitive advisories in the current toolchain. +The source and new templates pin patched `brace-expansion`, `fast-uri`, and both supported `undici` +major lines to avoid high-severity transitive advisories in the current toolchain. diff --git a/examples/basic/pnpm-workspace.yaml b/examples/basic/pnpm-workspace.yaml index 6f270af..fec240d 100644 --- a/examples/basic/pnpm-workspace.yaml +++ b/examples/basic/pnpm-workspace.yaml @@ -16,7 +16,8 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: - fast-uri: 3.1.7 + brace-expansion: 5.0.12 + fast-uri: 3.1.8 sharp: 0.35.4 'undici@^7.0.0': 7.29.1 'undici@^8.0.0': 8.10.2 diff --git a/examples/with-astro/apps/deploy/package.json b/examples/with-astro/apps/deploy/package.json index 47eb580..06d9c97 100644 --- a/examples/with-astro/apps/deploy/package.json +++ b/examples/with-astro/apps/deploy/package.json @@ -6,10 +6,12 @@ "scripts": { "lint": "eslint . --max-warnings 0", "check-types": "tsc --noEmit", - "test": "node --test" + "test": "node --test", + "validate": "cf deploy --dry-run" }, "devDependencies": { "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/site": "workspace:*", "@lasvegasfortransit/typescript-config": "0.6.1", "cf": "catalog:", "eslint": "catalog:", diff --git a/examples/with-astro/docs/development/tutorials/start-here.md b/examples/with-astro/docs/development/tutorials/start-here.md index 3646d2c..f22ffcc 100644 --- a/examples/with-astro/docs/development/tutorials/start-here.md +++ b/examples/with-astro/docs/development/tutorials/start-here.md @@ -34,7 +34,7 @@ prints one line per check: ok git hooks core.hooksPath is .githooks ok commit scopes .lvbt/commit-scopes.txt is present ok GitHub CLI gh is installed and signed in - ok Cloudflare wrangler is signed in; deployables: apps/site + ok Cloudflare cf ready for: apps/deploy preflight: all 7 checks passed ``` @@ -47,9 +47,9 @@ pnpm check ``` This is the same command CI runs: formatting, documentation links, the repository-shape rules, then -lint, typecheck, and tests for every package. On a fresh clone it passes. When it fails, the output -names the package and file; `pnpm check:fix` repairs everything a machine can (formatting and -auto-fixable lint findings). +lint, typecheck, tests, a site build, and a Cloudflare deploy dry run. On a fresh clone it passes. +When it fails, the output names the package and file; `pnpm check:fix` repairs formatting and +auto-fixable lint findings. ## 3. Make a change and commit it diff --git a/examples/with-astro/pnpm-workspace.yaml b/examples/with-astro/pnpm-workspace.yaml index 6f270af..fec240d 100644 --- a/examples/with-astro/pnpm-workspace.yaml +++ b/examples/with-astro/pnpm-workspace.yaml @@ -16,7 +16,8 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: - fast-uri: 3.1.7 + brace-expansion: 5.0.12 + fast-uri: 3.1.8 sharp: 0.35.4 'undici@^7.0.0': 7.29.1 'undici@^8.0.0': 8.10.2 diff --git a/examples/with-vite-react/apps/deploy/package.json b/examples/with-vite-react/apps/deploy/package.json index 47eb580..2415f96 100644 --- a/examples/with-vite-react/apps/deploy/package.json +++ b/examples/with-vite-react/apps/deploy/package.json @@ -6,10 +6,12 @@ "scripts": { "lint": "eslint . --max-warnings 0", "check-types": "tsc --noEmit", - "test": "node --test" + "test": "node --test", + "validate": "cf deploy --dry-run" }, "devDependencies": { "@lasvegasfortransit/eslint-config": "0.6.1", + "@lasvegasfortransit/app": "workspace:*", "@lasvegasfortransit/typescript-config": "0.6.1", "cf": "catalog:", "eslint": "catalog:", diff --git a/examples/with-vite-react/docs/development/tutorials/start-here.md b/examples/with-vite-react/docs/development/tutorials/start-here.md index dc39c88..acf377f 100644 --- a/examples/with-vite-react/docs/development/tutorials/start-here.md +++ b/examples/with-vite-react/docs/development/tutorials/start-here.md @@ -34,7 +34,7 @@ prints one line per check: ok git hooks core.hooksPath is .githooks ok commit scopes .lvbt/commit-scopes.txt is present ok GitHub CLI gh is installed and signed in - ok Cloudflare wrangler is signed in; deployables: apps/app + ok Cloudflare cf ready for: apps/deploy preflight: all 7 checks passed ``` @@ -47,9 +47,9 @@ pnpm check ``` This is the same command CI runs: formatting, documentation links, the repository-shape rules, then -lint, typecheck, and tests for every package. On a fresh clone it passes. When it fails, the output -names the package and file; `pnpm check:fix` repairs everything a machine can (formatting and -auto-fixable lint findings). +lint, typecheck, tests, an app build, and a Cloudflare deploy dry run. On a fresh clone it passes. +When it fails, the output names the package and file; `pnpm check:fix` repairs formatting and +auto-fixable lint findings. ## 3. Make a change and commit it diff --git a/examples/with-vite-react/pnpm-workspace.yaml b/examples/with-vite-react/pnpm-workspace.yaml index 6f270af..fec240d 100644 --- a/examples/with-vite-react/pnpm-workspace.yaml +++ b/examples/with-vite-react/pnpm-workspace.yaml @@ -16,7 +16,8 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: - fast-uri: 3.1.7 + brace-expansion: 5.0.12 + fast-uri: 3.1.8 sharp: 0.35.4 'undici@^7.0.0': 7.29.1 'undici@^8.0.0': 8.10.2 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb63fed..dcc878c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,7 +83,8 @@ catalogs: version: 4.141.0 overrides: - fast-uri: 3.1.7 + brace-expansion: 5.0.12 + fast-uri: 3.1.8 sharp: 0.35.4 undici@^7.0.0: 7.29.1 undici@^8.0.0: 8.10.2 @@ -1790,8 +1791,8 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@5.0.9: - resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} engines: {node: 20 || >=22} braces@3.0.3: @@ -2114,8 +2115,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.7: - resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -4786,7 +4787,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.7 + fast-uri: 3.1.8 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -4916,7 +4917,7 @@ snapshots: boolbase@1.0.0: {} - brace-expansion@5.0.9: + brace-expansion@5.0.12: dependencies: balanced-match: 4.0.4 @@ -5300,7 +5301,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.7: {} + fast-uri@3.1.8: {} fast-wrap-ansi@0.2.2: dependencies: @@ -5920,7 +5921,7 @@ snapshots: minimatch@10.2.6: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 minisearch@7.2.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 51aee07..c93f5f6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,7 +15,8 @@ minimumReleaseAge: 1440 # Temporary transitive pins for published security fixes not yet selected by # their direct dependents. overrides: - fast-uri: 3.1.7 + brace-expansion: 5.0.12 + fast-uri: 3.1.8 sharp: 0.35.4 'undici@^7.0.0': 7.29.1 'undici@^8.0.0': 8.10.2 diff --git a/tests/example.test.mjs b/tests/example.test.mjs index c09803e..741802e 100644 --- a/tests/example.test.mjs +++ b/tests/example.test.mjs @@ -137,7 +137,7 @@ for (const [name, { uses, deploys }] of Object.entries(examples)) { Object.assign(specifiers, manifest.dependencies, manifest.devDependencies); } for (const [dependency, range] of Object.entries(specifiers)) { - if (dependency.startsWith('@lasvegasfortransit/')) { + if (sharedPackages.some((shared) => dependency === `@lasvegasfortransit/${shared}`)) { assert.equal(range, version, `${dependency} must be pinned to ${version}`); } } @@ -436,7 +436,7 @@ test('source and generated repositories pin audited transitive fixes', async () ); assert.match( workspace, - /^overrides:\n {2}fast-uri: 3\.1\.7\n {2}sharp: 0\.35\.4\n {2}'undici@\^7\.0\.0': 7\.29\.1\n {2}'undici@\^8\.0\.0': 8\.10\.2\n {2}smol-toml: 1\.8\.0\n {2}svgo: 4\.1\.0$/m, + /^overrides:\n {2}brace-expansion: 5\.0\.12\n {2}fast-uri: 3\.1\.8\n {2}sharp: 0\.35\.4\n {2}'undici@\^7\.0\.0': 7\.29\.1\n {2}'undici@\^8\.0\.0': 8\.10\.2\n {2}smol-toml: 1\.8\.0\n {2}svgo: 4\.1\.0$/m, ); } }); diff --git a/tests/web-platform.test.mjs b/tests/web-platform.test.mjs index 890792a..90820fd 100644 --- a/tests/web-platform.test.mjs +++ b/tests/web-platform.test.mjs @@ -222,6 +222,26 @@ test('web profiles deploy once through cf and preserve Worker version previews', } }); +test('web profiles validate the cf bundle after building their app', () => { + const root = new URL('..', import.meta.url).pathname; + for (const [profile, app] of [ + ['with-astro', 'site'], + ['with-vite-react', 'app'], + ]) { + const example = path.join(root, 'examples', profile); + const result = spawnSync( + path.join(root, 'node_modules/turbo/bin/turbo'), + ['run', 'validate', '--dry-run=json', '--cwd', example], + { encoding: 'utf8' }, + ); + assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`); + const tasks = JSON.parse(result.stdout).tasks; + const deploy = tasks.find((task) => task.taskId === '@lasvegasfortransit/deploy#validate'); + assert.equal(deploy?.command, 'cf deploy --dry-run'); + assert.deepEqual(deploy.dependencies, [`@lasvegasfortransit/${app}#build`]); + } +}); + test('the updater accepts either a release or an exact commit, never both', () => fixture(async (root) => { const repository = new URL('..', import.meta.url).pathname;