@bascik/adapter-cloudflare 1.0.0-rc.1 → 1.0.0-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,95 +1,21 @@
1
- Elastic License 2.0
2
-
3
- URL: https://www.elastic.co/licensing/elastic-license
1
+ MIT License
4
2
 
5
3
  Copyright (c) 2026 Collin Thomas
6
4
 
7
- ## Acceptance
8
-
9
- By using the software, you agree to all of the terms and conditions below.
10
-
11
- ## Copyright License
12
-
13
- The licensor grants you a non-exclusive, royalty-free, worldwide,
14
- non-sublicensable, non-transferable license to use, copy, distribute, make
15
- available, and prepare derivative works of the software, in each case subject to
16
- the limitations and conditions below.
17
-
18
- ## Limitations
19
-
20
- You may not provide the software to third parties as a hosted or managed
21
- service, where the service provides users with access to any substantial set of
22
- the features or functionality of the software.
23
-
24
- You may not move, change, disable, or circumvent the license key functionality
25
- in the software, and you may not remove or obscure any functionality in the
26
- software that is protected by the license key.
27
-
28
- You may not alter, remove, or obscure any licensing, copyright, or other notices
29
- of the licensor in the software. Any use of the licensor's trademarks is subject
30
- to applicable law.
31
-
32
- ## Patents
33
-
34
- The licensor grants you a license, under any patent claims the licensor can
35
- license, or becomes able to license, to make, have made, use, sell, offer for
36
- sale, import and have imported the software, in each case subject to the
37
- limitations and conditions in this license. This license does not cover any
38
- patent claims that you cause to be infringed by modifications or additions to
39
- the software. If you or your company make any written claim that the software
40
- infringes or contributes to infringement of any patent, your patent license for
41
- the software granted under these terms ends immediately. If your company makes
42
- such a claim, your patent license ends immediately for work on behalf of your
43
- company.
44
-
45
- ## Notices
46
-
47
- You must ensure that anyone who gets a copy of any part of the software from you
48
- also gets a copy of these terms.
49
-
50
- If you modify the software, you must include in any modified copies of the
51
- software prominent notices stating that you have modified the software.
52
-
53
- ## No Other Rights
54
-
55
- These terms do not imply any licenses other than those expressly granted in
56
- these terms.
57
-
58
- ## Termination
59
-
60
- If you use the software in violation of these terms, such use is not licensed,
61
- and your licenses will automatically terminate. If the licensor provides you
62
- with a notice of your violation, and you cease all violation of this license no
63
- later than 30 days after you receive that notice, your licenses will be
64
- reinstated retroactively. However, if you violate these terms after such
65
- reinstatement, any additional violation of these terms will cause your licenses
66
- to terminate automatically and permanently.
67
-
68
- ## No Liability
69
-
70
- As far as the law allows, the software comes as is, without any warranty or
71
- condition, and the licensor will not be liable to you for any damages arising
72
- out of these terms or the use or nature of the software, under any kind of legal
73
- claim.
74
-
75
- ## Definitions
76
-
77
- The **licensor** is the entity offering these terms, and the **software** is the
78
- software the licensor makes available under these terms, including any portion
79
- of it.
80
-
81
- **you** refers to the individual or entity agreeing to these terms.
82
-
83
- **your company** is any legal entity, sole proprietorship, or other kind of
84
- organization that you work for, plus all organizations that have control over,
85
- are under the control of, or are under common control with that organization.
86
- **control** means ownership of substantially all the assets of an entity, or the
87
- power to direct its management and policies by vote, contract, or otherwise.
88
- Control can be direct or indirect.
89
-
90
- **your licenses** are all the licenses granted to you for the software under
91
- these terms.
92
-
93
- **use** means anything you do with the software requiring one of your licenses.
94
-
95
- **trademark** means trademarks, service marks, and similar rights.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -7,24 +7,38 @@ Cloudflare Workers with Static Assets and Cloudflare Pages hosting adapter for [
7
7
 
8
8
  ## Overview
9
9
 
10
- This adapter compiles Bascik request-time scripts and API routes into a Cloudflare Workers deployment bundle with static asset routing.
10
+ This adapter compiles Bascik request-time scripts and API routes into a Cloudflare Workers deployment bundle with static asset routing. Install it in a Bascik project that deploys to Cloudflare (Node.js 22.22 or newer), or start one with `npm create bascik@rc my-site -- --template cloudflare`:
11
+
12
+ ```sh
13
+ npm install --save-dev @bascik/adapter-cloudflare wrangler
14
+ ```
11
15
 
12
16
  See the [Cloudflare deployment guide](https://bascik.dev/deployment/cloudflare) for setup instructions, recipes, and limits.
13
17
 
18
+ See it live: [cloudflare-adapter.bascik.dev](https://cloudflare-adapter.bascik.dev/) is a Bascik site deployed with this adapter. Its [product catalog](https://cloudflare-adapter.bascik.dev/catalog?q=frother) renders the `<product-card>` tags a server script returns, and the [streamed catalog](https://cloudflare-adapter.bascik.dev/catalog-stream) streams them in batches from the Worker.
19
+
14
20
  ## Targets and Variants
15
21
 
16
22
  - `cloudflare` / `cloudflare-workers` (Default): Outputs `worker.js`, `wrangler.jsonc`, and `public/` for Cloudflare Workers with Static Assets.
17
- - `cloudflare-pages` (Legacy): Outputs `public/_worker.js` and `public/_routes.json` for Cloudflare Pages.
23
+ - `cloudflare-pages` (Legacy): Outputs `public/_worker.js` and `public/_routes.json` for Cloudflare Pages. Set the Pages project's compatibility date (the pinned one or later) and the `nodejs_compat` flag, for Production and Preview, in the dashboard: `wrangler pages deploy` does not set them.
18
24
 
19
25
  ## Quickstart
20
26
 
27
+ Develop in Cloudflare's local runtime (workerd), with source watching and browser live reload:
28
+
29
+ ```sh
30
+ bascik --target cloudflare
31
+ ```
32
+
33
+ Open `http://127.0.0.1:8787`; use `--port` and `--host` to override the public address. Bascik runs full production adapter builds, starts Wrangler, and proxies the runtime over local HTTP. Source edits rebuild the bundle and reload connected browsers. Requests can receive 503 while rebuilding or after a failed build; the watcher stays alive and retries after the next edit. The proxy is HTTP only, regardless of the Node server's TLS configuration. Live reload is injected by the local proxy, never written into production artifacts. Bare `bascik` remains the Node development server.
34
+
21
35
  Build for Cloudflare Workers with Static Assets:
22
36
 
23
37
  ```sh
24
38
  bascik --build --target cloudflare
25
39
  ```
26
40
 
27
- Preview locally with Wrangler from the emitted target directory:
41
+ Preview a production build locally with Wrangler from the emitted target directory (without Bascik's source watcher or live reload):
28
42
 
29
43
  ```sh
30
44
  cd dist/.bascik/cloudflare
@@ -40,4 +54,61 @@ npx wrangler deploy
40
54
 
41
55
  ## Compatibility Date
42
56
 
43
- The adapter pins a supported Cloudflare compatibility date and `nodejs_compat` compatibility flag to ensure local workerd testing parity.
57
+ The adapter pins a supported Cloudflare compatibility date and `nodejs_compat` compatibility flag to ensure local workerd testing parity. An authored `compatibility_date` in your Wrangler config is kept; request-time `node:*` imports are then checked against it (and each `env.<name>` date), since `node:http`, `node:fs`, `node:os` and `node:perf_hooks` exist only from a date on, and the build notes print the date and flags the Worker deploys with.
58
+
59
+ ## Your Wrangler Config
60
+
61
+ Put a `wrangler.jsonc` (or `wrangler.json` or `wrangler.toml`) in the project root. The build writes `dist/.bascik/cloudflare/wrangler.jsonc` from it and never edits your file.
62
+
63
+ - **Carried over as written:** every key the adapter does not own, at the top level and in each `env.<name>`: `preview_urls`, `previews`, `workers_dev`, `routes`, `vars`, bindings (`kv_namespaces`, `d1_databases`, `r2_buckets`, ...), `observability`, `limits`, `placement`, and keys the adapter does not know. Wrangler validates them.
64
+ - **Owned by the adapter:** `main` (always `worker.js`), `assets.directory` (always `./public`), and `assets.binding` (always `ASSETS`, the binding the generated Worker reads). An authored `main` or `assets.directory` is replaced and the build prints a warning naming the file and key. An authored `assets.binding` other than `ASSETS` fails the build.
65
+ - **Merged:** `compatibility_flags` are your flags plus `nodejs_compat`. Your other `assets` keys (`html_handling`, `base_path`, ...) are kept, and your `not_found_handling` replaces the default `404-page`. `assets.run_worker_first` is computed from your pages and API routes; your `true` or `["/*"]` sends every request to the Worker, and other patterns you list are added to the computed ones.
66
+ - **Rebased:** paths Wrangler reads relative to the config file are rewritten so they name the same files from the output folder: `$schema`, `tsconfig`, `base_dir`, `build.cwd`, `build.watch_dir`, `d1_databases[].migrations_dir` and `migrations_pattern`, `site.bucket`, `wasm_modules`, `text_blobs`, `data_blobs`, `containers[].image_build_context`, `containers[].images.<name>.dockerfile` and `build_context`, and a `containers[].image` spelled as a path. Two defaults Wrangler takes from the config's folder are written out so they still point at the project root: a `build.command` without `build.cwd` gets `cwd` set to the project root, and a D1 binding with neither `migrations_dir` nor `migrations_pattern` gets `migrations_dir` set to the project's `migrations` folder. Absolute paths and URLs are kept. Other files Wrangler looks for beside the config file, such as `.dev.vars`, `.env` and a default `tsconfig.json`, are not carried over: run `wrangler dev` or `wrangler types` with those files in the output folder, or pass their paths.
67
+
68
+ The Worker name comes from `CLOUDFLARE_WORKER_NAME`, `WORKER_NAME`, or `CF_PAGES_PROJECT_NAME`, then your config's `name`, then the `package.json` name. The rest of your config is carried over whichever source names the Worker.
69
+
70
+ ## Demo Worker
71
+
72
+ [cloudflare-adapter.bascik.dev](https://cloudflare-adapter.bascik.dev/) is the E2E fixture, `e2e/fixture/`, deployed as the Worker `cloudflare-adapter`. Its `e2e/fixture/wrangler.jsonc` holds the whole Worker definition: the custom domain (`routes` with `custom_domain: true`), `workers_dev: false`, `preview_urls: true`, and the empty `previews` block that `wrangler preview` requires. The E2E lane builds the fixture with `--target cloudflare-pages`, which does not read that file.
73
+
74
+ From the repo root:
75
+
76
+ ```sh
77
+ yarn adapter:cf:demo:build # build pkg, the adapter, then the fixture with --target cloudflare
78
+ yarn adapter:cf:demo:dev # watched adapter dev in local workerd on port 8787
79
+ yarn adapter:cf:demo:preview # build, then wrangler preview (a Preview named after the git branch)
80
+ yarn adapter:cf:demo:deploy # build, then wrangler deploy to production
81
+ ```
82
+
83
+ The workspace script `demo:dev` runs `bascik --target cloudflare` from the fixture root. `demo:build`, `demo:preview`, and `demo:deploy` remain separate production steps for CI.
84
+
85
+ Watched development launches Wrangler from the project root, pointing it at the generated Worker config or Pages public directory by absolute path. Its working directory stays valid even when another build replaces the generated output.
86
+ Local bindings persist under the project's `.wrangler/state/`, outside generated output, so source rebuilds do not delete KV, D1, R2, or Durable Object data.
87
+
88
+ ## Development
89
+
90
+ From the repository root:
91
+
92
+ ```sh
93
+ yarn adapter:cf:build # compile dist/
94
+ yarn adapter:cf:typecheck # TypeScript type check
95
+ yarn adapter:cf:unit # unit tests
96
+ yarn adapter:cf:coverage # unit tests with coverage, written to test-coverage.json
97
+ yarn adapter:cf:e2e # build the fixture and run Playwright against it in local workerd
98
+ yarn adapter:cf:e2e:dev # real watched platform runtime and browser reload tests
99
+ ```
100
+
101
+ The E2E lanes use the built compiler and adapter, so run `yarn pkg:build && yarn adapter:cf:build` first. The watched lane runs `adapters/e2e/playwright.dev.config.ts` against the real Wrangler runtime; CI runs it separately from production acceptance. `yarn adapter:e2e:dev` runs both platforms after building both adapters.
102
+
103
+ Cloudflare and Netlify run the same [demo browser contract](../e2e/demo-contract.test.ts)
104
+ against their real runtimes. Both demos expose `/`, `/server?name=collin`,
105
+ `/stream`, `/stream-append`, `/mixed`, `/catalog`, `/catalog-stream`, `/api-demo`,
106
+ `/errors`, and `/static` with matching titles and navigation. The `/static`
107
+ page demonstrates scoped client scripts and independent counters; the overview
108
+ only links to the demos. The contract checks static
109
+ client scripts, escaped input, product rendering and filtering, API dispatch,
110
+ no-JavaScript stream ordering, and safe failures. Platform-specific context and
111
+ routing assertions remain in this adapter's own suite. Error-demo requests
112
+ intentionally generate diagnostics.
113
+
114
+ CI deploys the demo Worker after every other stage passes, and posts a preview URL on pull requests. [DEPLOYMENT.md](../../DEPLOYMENT.md) is the runbook.
package/dist/build.d.ts CHANGED
@@ -14,6 +14,14 @@ export declare const buildInvocationRoutes: (input: {
14
14
  base: string;
15
15
  dynamicPagePaths: string[];
16
16
  hasApiRoutes: boolean;
17
+ /** A static 404.html exists; its URLs must reach the worker to answer 404. */
18
+ hasStaticNotFoundPage?: boolean;
17
19
  }) => InvocationRoutes;
18
20
  export declare const detectControlCollisions: (publicPaths: string[], variant: string) => string[];
21
+ /**
22
+ * Whether the authored `assets.run_worker_first` sends every request of the
23
+ * site to the Worker first: `true`, or a list with `/*` (or the base's
24
+ * `/shop/*`) and no `!` exclusion.
25
+ */
26
+ export declare const runsWorkerFirst: (assets: unknown, base: string) => boolean;
19
27
  export declare const build: (context: AdapterBuildContext) => Promise<AdapterBuildResult>;