devflare 1.0.0-next.22 → 1.0.0-next.24

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.
Files changed (146) hide show
  1. package/LLM.md +221 -7
  2. package/dist/account-5nm1xn0v.js +475 -0
  3. package/dist/account-j8nfggg4.js +475 -0
  4. package/dist/account-qhe8vtds.js +475 -0
  5. package/dist/bridge/miniflare.d.ts +1 -1
  6. package/dist/bridge/miniflare.d.ts.map +1 -1
  7. package/dist/browser.d.ts +35 -15
  8. package/dist/browser.d.ts.map +1 -1
  9. package/dist/browser.js +4 -2
  10. package/dist/build-vctfnmsf.js +54 -0
  11. package/dist/build-vy95gy3f.js +54 -0
  12. package/dist/build-yzx0gsaj.js +54 -0
  13. package/dist/cli/commands/build-artifacts.d.ts.map +1 -1
  14. package/dist/cli/commands/config.d.ts.map +1 -1
  15. package/dist/cli/commands/deploy/prepare.d.ts.map +1 -1
  16. package/dist/cli/commands/deploy.d.ts.map +1 -1
  17. package/dist/cli/commands/type-generation/generator.d.ts +4 -2
  18. package/dist/cli/commands/type-generation/generator.d.ts.map +1 -1
  19. package/dist/cli/commands/types.d.ts.map +1 -1
  20. package/dist/cli/index.js +1 -1
  21. package/dist/config/compiler/types.d.ts +1 -1
  22. package/dist/config/compiler/types.d.ts.map +1 -1
  23. package/dist/config/define.d.ts +7 -4
  24. package/dist/config/define.d.ts.map +1 -1
  25. package/dist/config/env-vars.d.ts +309 -0
  26. package/dist/config/env-vars.d.ts.map +1 -0
  27. package/dist/config/index.d.ts +2 -1
  28. package/dist/config/index.d.ts.map +1 -1
  29. package/dist/config/loader.d.ts.map +1 -1
  30. package/dist/config/local-dev-vars.d.ts +2 -2
  31. package/dist/config/local-dev-vars.d.ts.map +1 -1
  32. package/dist/config/schema-env.d.ts +28 -8
  33. package/dist/config/schema-env.d.ts.map +1 -1
  34. package/dist/config/schema-runtime.d.ts +11 -1
  35. package/dist/config/schema-runtime.d.ts.map +1 -1
  36. package/dist/config/schema-types-bindings-platform.d.ts +378 -0
  37. package/dist/config/schema-types-bindings-platform.d.ts.map +1 -0
  38. package/dist/config/schema-types-bindings-resources.d.ts +551 -0
  39. package/dist/config/schema-types-bindings-resources.d.ts.map +1 -0
  40. package/dist/config/schema-types-bindings.d.ts +254 -0
  41. package/dist/config/schema-types-bindings.d.ts.map +1 -0
  42. package/dist/config/schema-types-build.d.ts +86 -0
  43. package/dist/config/schema-types-build.d.ts.map +1 -0
  44. package/dist/config/schema-types-runtime.d.ts +885 -0
  45. package/dist/config/schema-types-runtime.d.ts.map +1 -0
  46. package/dist/config/schema-types.d.ts +377 -0
  47. package/dist/config/schema-types.d.ts.map +1 -0
  48. package/dist/config/schema.d.ts +47 -18
  49. package/dist/config/schema.d.ts.map +1 -1
  50. package/dist/config-entry.d.ts +2 -0
  51. package/dist/config-entry.d.ts.map +1 -1
  52. package/dist/config-entry.js +3 -1
  53. package/dist/config-gq5jh4cx.js +105 -0
  54. package/dist/config-rq32csms.js +105 -0
  55. package/dist/config-vec13050.js +105 -0
  56. package/dist/deploy-01j0ep5n.js +1055 -0
  57. package/dist/deploy-krj3k9zm.js +1055 -0
  58. package/dist/deploy-mem96qyn.js +1066 -0
  59. package/dist/deploy-tjypkhg7.js +1055 -0
  60. package/dist/dev-apkr7cfv.js +2597 -0
  61. package/dist/dev-bh581ew3.js +2597 -0
  62. package/dist/dev-gn5y93z9.js +2597 -0
  63. package/dist/dev-server/server.d.ts.map +1 -1
  64. package/dist/doctor-9asw8x18.js +259 -0
  65. package/dist/doctor-h5q28qt1.js +259 -0
  66. package/dist/doctor-khk550tw.js +259 -0
  67. package/dist/env.d.ts +10 -0
  68. package/dist/env.d.ts.map +1 -1
  69. package/dist/index-0bv2qjs1.js +1555 -0
  70. package/dist/index-3tkzn06q.js +413 -0
  71. package/dist/index-4j9ah79n.js +1033 -0
  72. package/dist/index-8fyz6gcm.js +699 -0
  73. package/dist/index-97z629zr.js +109 -0
  74. package/dist/index-b28c4yr4.js +1205 -0
  75. package/dist/index-bfjpjs07.js +581 -0
  76. package/dist/index-c8p4njqy.js +479 -0
  77. package/dist/index-cna43592.js +1573 -0
  78. package/dist/index-cr06zrgw.js +1033 -0
  79. package/dist/index-cwjjdtgn.js +74 -0
  80. package/dist/index-d00njc1f.js +147 -0
  81. package/dist/index-dgeamyfk.js +1426 -0
  82. package/dist/index-dref9ecb.js +476 -0
  83. package/dist/index-e151t4ge.js +895 -0
  84. package/dist/index-e7kakw0j.js +1033 -0
  85. package/dist/index-f1g5jdm8.js +1426 -0
  86. package/dist/index-f46984zs.js +1554 -0
  87. package/dist/index-ftf7yqhs.js +74 -0
  88. package/dist/index-grk8pzhr.js +185 -0
  89. package/dist/index-h332fg62.js +1205 -0
  90. package/dist/index-hzmpecq9.js +52 -0
  91. package/dist/index-j1csb7gb.js +581 -0
  92. package/dist/index-j7x7f72h.js +185 -0
  93. package/dist/index-ja2rdbt0.js +476 -0
  94. package/dist/index-jkqbjwt2.js +476 -0
  95. package/dist/index-kc207nyr.js +52 -0
  96. package/dist/index-meq8ydc0.js +895 -0
  97. package/dist/index-mh5renra.js +895 -0
  98. package/dist/index-myfjejs0.js +185 -0
  99. package/dist/index-p9xq83p7.js +147 -0
  100. package/dist/index-q15nj71j.js +52 -0
  101. package/dist/index-qkfvd3cs.js +109 -0
  102. package/dist/index-qqp65pyv.js +699 -0
  103. package/dist/index-rnz879kf.js +1426 -0
  104. package/dist/index-s0fmwxbk.js +74 -0
  105. package/dist/index-s96e5dd9.js +699 -0
  106. package/dist/index-stzx8nc4.js +111 -0
  107. package/dist/index-th4vrnbk.js +1205 -0
  108. package/dist/index-vtcmsgaf.js +581 -0
  109. package/dist/index-x2k3awjs.js +147 -0
  110. package/dist/index-x8x547tz.js +1426 -0
  111. package/dist/index-xxxd0mvw.js +109 -0
  112. package/dist/index.d.ts +1 -1
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +8 -6
  115. package/dist/login-280p2cm9.js +77 -0
  116. package/dist/login-4n266whq.js +77 -0
  117. package/dist/login-g9rb7dj3.js +77 -0
  118. package/dist/previews-3m3ffpaw.js +1337 -0
  119. package/dist/previews-tr8sm03d.js +1337 -0
  120. package/dist/previews-ykamw25e.js +1337 -0
  121. package/dist/productions-4m1pd6ts.js +505 -0
  122. package/dist/productions-62y489ff.js +505 -0
  123. package/dist/productions-cgn3fz7d.js +505 -0
  124. package/dist/runtime/exports.d.ts +23 -0
  125. package/dist/runtime/exports.d.ts.map +1 -1
  126. package/dist/runtime/index.d.ts +1 -1
  127. package/dist/runtime/index.d.ts.map +1 -1
  128. package/dist/runtime/index.js +5 -3
  129. package/dist/secrets-4050kqf5.js +91 -0
  130. package/dist/secrets-gywxctdh.js +91 -0
  131. package/dist/secrets-p112cajt.js +91 -0
  132. package/dist/sveltekit/index.js +4 -4
  133. package/dist/test/index.js +23 -11
  134. package/dist/test/resolve-service-bindings.d.ts +1 -1
  135. package/dist/test/resolve-service-bindings.d.ts.map +1 -1
  136. package/dist/test/simple-context-lifecycle.d.ts.map +1 -1
  137. package/dist/types-17kkqw37.js +705 -0
  138. package/dist/types-apmt10yj.js +705 -0
  139. package/dist/types-ttrrgdfj.js +705 -0
  140. package/dist/vite/index.js +5 -5
  141. package/dist/vite/plugin-context.d.ts.map +1 -1
  142. package/dist/vite/plugin-programmatic.d.ts.map +1 -1
  143. package/dist/worker-2k1jyr6p.js +513 -0
  144. package/dist/worker-4fd49jm0.js +513 -0
  145. package/dist/worker-jqgn6jyj.js +513 -0
  146. package/package.json +1 -1
package/LLM.md CHANGED
@@ -13,7 +13,7 @@ It is meant to read like a proper markdown handbook rather than a second source
13
13
  - Links use the same `/docs/...` routes as the documentation site.
14
14
 
15
15
  ## Documentation map
16
- This export covers 146 pages across 5 top-level groups.
16
+ This export covers 147 pages across 5 top-level groups.
17
17
 
18
18
  ### Quickstart
19
19
  See why Devflare exists, build the smallest safe first worker, and move into routes, bindings, previews, and tests when the app needs them.
@@ -40,6 +40,7 @@ Keep the day-to-day Devflare surfaces easy to scan: runtime model, HTTP split, a
40
40
  - [Worker surfaces](/docs/worker-surfaces) — Devflare can compose or wrap several Worker surfaces into one generated entrypoint, but the authored source of truth should stay in explicit files such as `src/fetch.ts`, `src/queue.ts`, `src/scheduled.ts`, and `src/email.ts`.
41
41
  - [Generated types](/docs/generated-types) — `devflare types` turns config, discovered Durable Objects, named entrypoints, and cross-worker references into one generated TypeScript contract instead of a pile of hand-maintained env guesswork.
42
42
  - [Environments](/docs/config-environments) — Keep one base config, layer environment-specific overrides with `config.env`, and let Devflare resolve preview or production details only in the commands that actually need them.
43
+ - [Typed env vars](/docs/typed-env-vars) — Use `env.NAME` descriptors inside `defineConfig({ vars })`, parse or default them in config, and read the resulting typed values at runtime with `import { vars } from "devflare"`.
43
44
  - [Previews](/docs/config-previews) — Use `preview.scope()` for bindings that should belong to one preview scope. Devflare materializes names like `notes-db-next`, provisions or reuses the preview-only resources it can manage, and lets you clean them up by the same scope later without touching production resources.
44
45
  - [Runtime & deploy settings](/docs/runtime-deploy-settings) — Use config for account context, compatibility posture, assets, deployment routes, WebSocket proxy rules, migrations, observability, limits, and preview cron behavior instead of rediscovering those settings in scripts later.
45
46
 
@@ -2207,7 +2208,7 @@ That is what this page is for. The example below touches the major current top-l
2207
2208
  Hover any property in the config to see what that lane means. The example is intentionally broad, but the dedicated pages still own the deeper caveats and richer nested variants.
2208
2209
 
2209
2210
  ```ts
2210
- import { defineConfig } from 'devflare/config'
2211
+ import { defineConfig, env } from 'devflare/config'
2211
2212
 
2212
2213
  export default defineConfig({
2213
2214
  name: 'docs-platform',
@@ -2294,7 +2295,12 @@ export default defineConfig({
2294
2295
  crons: ['0 */6 * * *']
2295
2296
  },
2296
2297
  vars: {
2297
- APP_ENV: 'development'
2298
+ APP_ENV: 'development',
2299
+ mongo: {
2300
+ uri: env.MONGOURI,
2301
+ database: env.MONGODATABASE
2302
+ },
2303
+ retries: env.RETRIES.parse(Number)
2298
2304
  },
2299
2305
  secrets: {
2300
2306
  API_TOKEN: {
@@ -2303,7 +2309,7 @@ export default defineConfig({
2303
2309
  },
2304
2310
  routes: [
2305
2311
  {
2306
- pattern: 'docs.example.com/*',
2312
+ pattern: 'docs.example.com',
2307
2313
  custom_domain: true
2308
2314
  }
2309
2315
  ],
@@ -2904,8 +2910,8 @@ The replace-arrays rule is the one most likely to surprise someone arriving from
2904
2910
 
2905
2911
  ##### Key points
2906
2912
 
2907
- - Use `.env` for inputs that exist while `devflare.config.*` is being evaluated. Devflare prefers a workspace-root `.env` when it finds a workspace ancestor, otherwise it falls back to the nearest ancestor `.env`.
2908
- - Use `vars` for string values that should compile into generated Worker-facing output.
2913
+ - Use `.env` and `.env.dev` for config-time inputs. Devflare reads those files itself from the config directory upward, with closer files winning and `.env` overriding `.env.dev` in the same directory.
2914
+ - Use `vars` for values that should compile into Worker-facing output, including nested typed values produced by `env.NAME` descriptors.
2909
2915
  - Use `secrets` to declare runtime secret binding names, not to store those secret values in config. Today that is mostly schema and type metadata: the schema accepts `{ required: false }`, but generated env typing still treats declared secrets as present and Devflare does not currently turn that flag into a separate deploy-time guarantee.
2910
2916
  - Use `.env.example` to document config-time inputs for the team instead of leaving those values to memory or chat scrollback.
2911
2917
 
@@ -2915,6 +2921,139 @@ The replace-arrays rule is the one most likely to surprise someone arriving from
2915
2921
 
2916
2922
  ---
2917
2923
 
2924
+ ### Resolve `.env` values through typed config vars instead of scattering process env reads
2925
+
2926
+ > Use `env.NAME` descriptors inside `defineConfig({ vars })`, parse or default them in config, and read the resulting typed values at runtime with `import { vars } from "devflare"`.
2927
+
2928
+ | Field | Value |
2929
+ | --- | --- |
2930
+ | Route | [`/docs/typed-env-vars`](/docs/typed-env-vars) |
2931
+ | Group | Devflare |
2932
+ | Navigation title | Typed env vars |
2933
+ | Eyebrow | Configuration |
2934
+
2935
+ Devflare vars can now be a typed bridge from local `.env` files into Worker runtime code. The config owns which variables are required, optional, parsed, or dev-only, while application code reads the resolved shape through the `vars` runtime helper.
2936
+
2937
+ #### At a glance
2938
+
2939
+ | Fact | Value |
2940
+ | --- | --- |
2941
+ | Config import | `import { defineConfig, env } from 'devflare/config'` |
2942
+ | Runtime import | `import { vars } from 'devflare'` |
2943
+ | File order | Parents first, then closer directories; `.env.dev` first, `.env` last |
2944
+ | Missing build vars | Build fails with a nested missing-variable report |
2945
+
2946
+ #### Declare the runtime shape in config
2947
+
2948
+ The `env` export from `devflare/config` does not read the variable immediately. It creates a descriptor that Devflare resolves when it starts dev, builds artifacts, or prints a phase-resolved config.
2949
+
2950
+ That keeps config import cheap and lets Devflare report every missing variable at once, using the nested path from `vars` instead of a generic process-env crash.
2951
+
2952
+ ##### Example — Nested vars with required, optional, parsed, defaulted, and dev-only values
2953
+
2954
+ ```ts
2955
+ import { defineConfig, env } from 'devflare/config'
2956
+
2957
+ export default defineConfig({
2958
+ name: 'voices-api',
2959
+ vars: {
2960
+ secret: env.SECRET,
2961
+ mongo: {
2962
+ uri: env.MONGOURI,
2963
+ database: env.MONGODATABASE
2964
+ },
2965
+ retries: env.RETRIES.parse(Number),
2966
+ optionalLabel: env.OPTIONAL_LABEL.optional(),
2967
+ mode: env.APP_MODE.default('local'),
2968
+ mockTenantId: env.MOCK_TENANT_ID.dev(123)
2969
+ }
2970
+ })
2971
+ ```
2972
+
2973
+ #### Read resolved values through the runtime `vars` helper
2974
+
2975
+ At runtime, Devflare exposes the resolved values on the Worker environment and through the `vars` helper. The helper is typed from `devflare types`, so parser return values and nested objects stay visible to TypeScript.
2976
+
2977
+ Unparsed environment descriptors resolve to strings. Parsed descriptors use the parser return type, defaults contribute their value type, and optional descriptors become optional properties.
2978
+
2979
+ ##### Example — Runtime code can use the nested shape directly
2980
+
2981
+ ###### File — src/fetch.ts
2982
+
2983
+ ```ts
2984
+ import { vars } from 'devflare'
2985
+
2986
+ export default {
2987
+ async fetch() {
2988
+ return Response.json({
2989
+ database: vars.mongo.database,
2990
+ retries: vars.retries
2991
+ })
2992
+ }
2993
+ }
2994
+ ```
2995
+
2996
+ #### Let Devflare parse `.env` files itself
2997
+
2998
+ Devflare reads `.env.dev` and `.env` from the config directory and every parent directory. Parent files load first, then closer files override them. Within one directory, `.env.dev` loads first and `.env` wins last.
2999
+
3000
+ The parser does not expand `$OTHER_VARIABLE` references. Values such as passwords, MongoDB connection strings, and shell-looking fragments are read as written instead of being interpreted by Bun.
3001
+
3002
+ > **Note — Process env still wins over files**
3003
+ >
3004
+ > CI-provided environment variables and explicit shell exports override `.env` file values. Dotenv files fill in missing process variables; they do not stomp values the process already had.
3005
+
3006
+ ##### Example — The later `.env` value overrides the earlier `.env.dev` value
3007
+
3008
+ ###### File — .env
3009
+
3010
+ ```dotenv
3011
+ # .env.dev
3012
+ SECRET=local-secret
3013
+ MONGOURI=mongodb://127.0.0.1:27017
3014
+ MONGODATABASE=voices_dev
3015
+ RETRIES=1
3016
+
3017
+ # .env
3018
+ MONGODATABASE=voices
3019
+ ```
3020
+
3021
+ #### Missing required values fail build and pause dev
3022
+
3023
+ Required is the default because a config variable usually means the Worker cannot run honestly without that value. Build and config-inspection commands fail with a grouped report that points at the nested `vars` path and the missing environment variable name.
3024
+
3025
+ Dev mode is gentler. It prints the same report, waits for `.env` or `.env.dev` to change, and then retries startup. That makes the local loop fixable without restarting the command.
3026
+
3027
+ ##### Example — Missing variables are grouped by the config path that required them
3028
+
3029
+ ###### File — missing-env-vars.txt
3030
+
3031
+ ```text
3032
+ These environment variables are missing:
3033
+
3034
+ secret: SECRET
3035
+ mongo:
3036
+ uri: MONGOURI
3037
+ ```
3038
+
3039
+ #### Use helpers to make intent explicit
3040
+
3041
+ ##### Reference table
3042
+
3043
+ | Helper | Meaning | Example |
3044
+ | --- | --- | --- |
3045
+ | `env.NAME` | Required string value. | `env.SECRET` |
3046
+ | `.optional()` | Missing value is allowed and omitted. | `env.OPTIONAL_LABEL.optional()` |
3047
+ | `.parse(fn)` / `.parser(fn)` | Transform the string from env files into a typed runtime value. | `env.RETRIES.parse(Number)` |
3048
+ | `.default(value)` | Use a fallback in every mode when the env value is missing. | `env.APP_MODE.default('local')` |
3049
+ | `.dev(value)` | Use a fallback only in dev when the env value is missing. | `env.MOCK_TENANT_ID.dev(123)` |
3050
+
3051
+ > **Warning — Dev-only defaults are still required in build**
3052
+ >
3053
+ > `.dev(value)` is intentionally local-only. If the same variable may be missing in build too, use `.default(value)` or `.optional()` instead.
3054
+
3055
+ ---
3056
+
2918
3057
  ### Author preview-scoped bindings so preview deploys can own disposable infrastructure
2919
3058
 
2920
3059
  > Use `preview.scope()` for bindings that should belong to one preview scope. Devflare materializes names like `notes-db-next`, provisions or reuses the preview-only resources it can manage, and lets you clean them up by the same scope later without touching production resources.
@@ -3109,12 +3248,83 @@ The important habit is that runtime posture should be reviewable in source contr
3109
3248
  >
3110
3249
  > Devflare already includes `nodejs_compat` and `nodejs_als`. Keep `compatibilityFlags` focused on the extra posture your package actually needs.
3111
3250
 
3251
+ #### Choose the Cloudflare endpoint model first
3252
+
3253
+ Cloudflare documents three inbound endpoint models for Workers: Custom Domains, normal Workers routes, and the automatic `workers.dev` route. They are not interchangeable, and Devflare keeps that distinction in the top-level `routes` config instead of inventing a second routing vocabulary.
3254
+
3255
+ Use a Custom Domain when the Worker is the origin for a whole hostname. Use a normal Workers route when a Worker should sit in front of an existing proxied hostname, match a wildcard host, or match a path prefix. Use `workers.dev` for getting started or preview-style reachability, and disable it when production should only be reachable through your own domain.
3256
+
3257
+ ##### Reference table
3258
+
3259
+ | Goal | Devflare config shape | Cloudflare behavior |
3260
+ | --- | --- | --- |
3261
+ | Worker owns every path on one hostname | `routes: [{ pattern: "app.example.com", custom_domain: true }]` | Custom Domains match the exact hostname; paths and query strings do not participate in the match. |
3262
+ | Worker intercepts a path or wildcard host in a Cloudflare zone | `routes: [{ pattern: "app.example.com/api/*", zone_name: "example.com" }]` | Normal routes use route patterns, may include `*`, and the most specific matching route wins. |
3263
+ | Worker remains reachable on the account subdomain | Default generated Wrangler config keeps `workers_dev: true`. | Cloudflare assigns `<worker>.<account>.workers.dev`; Cloudflare recommends routes or custom domains for production. |
3264
+
3265
+ > **Note — Routes can sit in front of Custom Domains**
3266
+ >
3267
+ > Cloudflare treats a Worker on a Custom Domain as an origin. A more specific normal route on the same hostname can run first, then call `fetch(request)` to invoke the Custom Domain Worker behind it.
3268
+
3269
+ > **Warning — Same-zone fetch is different for routes and Custom Domains**
3270
+ >
3271
+ > Cloudflare documents that Custom Domains can be invoked by same-zone `fetch()`, while normal routes cannot be the target of same-zone `fetch()` and should use service bindings for Worker-to-Worker calls.
3272
+
3273
+ ##### Example — Custom Domain for a Worker-owned hostname
3274
+
3275
+ ```ts
3276
+ import { defineConfig } from 'devflare/config'
3277
+
3278
+ export default defineConfig({
3279
+ name: 'app-worker',
3280
+ routes: [
3281
+ {
3282
+ pattern: 'app.example.com',
3283
+ custom_domain: true
3284
+ }
3285
+ ]
3286
+ })
3287
+ ```
3288
+
3289
+ ##### Example — Workers route for path or wildcard matching
3290
+
3291
+ ```ts
3292
+ import { defineConfig } from 'devflare/config'
3293
+
3294
+ export default defineConfig({
3295
+ name: 'api-proxy-worker',
3296
+ routes: [
3297
+ {
3298
+ pattern: 'app.example.com/api/*',
3299
+ zone_name: 'example.com'
3300
+ }
3301
+ ]
3302
+ })
3303
+ ```
3304
+
3305
+ ##### Example — Disable workers.dev when only custom endpoints should serve production
3306
+
3307
+ ```ts
3308
+ import { defineConfig } from 'devflare/config'
3309
+
3310
+ export default defineConfig({
3311
+ name: 'scratch-worker',
3312
+ wrangler: {
3313
+ passthrough: {
3314
+ workers_dev: false
3315
+ }
3316
+ }
3317
+ })
3318
+ ```
3319
+
3112
3320
  #### Keep deployment shape in config, not in app routing or shell scripts
3113
3321
 
3114
3322
  Several config keys answer deployment questions rather than application-routing questions. Keeping those lanes separate is what stops app URLs, Cloudflare routes, and dev-only WebSocket proxy behavior from collapsing into one blurry story.
3115
3323
 
3116
3324
  If the package serves static assets, mounts a custom domain, or proxies Durable Object WebSockets in development, that shape should live in config beside the rest of the deployment contract.
3117
3325
 
3326
+ Custom Domains are host-only: use `custom_domain: true` with a bare hostname such as `docs.example.com`. For wildcard or path matching such as `docs.example.com/*` or `docs.example.com/api/*`, use a normal Workers route with `zone_name` or `zone_id` instead.
3327
+
3118
3328
  ##### Reference table
3119
3329
 
3120
3330
  | Key | What it controls | Common use |
@@ -3127,6 +3337,10 @@ If the package serves static assets, mounts a custom domain, or proxies Durable
3127
3337
  >
3128
3338
  > `files.routes` controls your app route tree. Top-level `routes` controls Cloudflare deployment routing. Keep those ideas separate so the package stays reviewable.
3129
3339
 
3340
+ > **Warning — Custom Domains are not wildcard routes**
3341
+ >
3342
+ > Cloudflare Custom Domains match the hostname exactly and ignore paths. Do not add `/*` when `custom_domain: true`; a request to any path on that hostname will already invoke the Worker.
3343
+
3130
3344
  ##### Example — One place for runtime posture and deployment-facing settings
3131
3345
 
3132
3346
  ```ts
@@ -3141,7 +3355,7 @@ export default defineConfig({
3141
3355
  binding: 'ASSETS'
3142
3356
  },
3143
3357
  routes: [
3144
- { pattern: 'docs.example.com/*', custom_domain: true }
3358
+ { pattern: 'docs.example.com', custom_domain: true }
3145
3359
  ],
3146
3360
  wsRoutes: [
3147
3361
  {