@jimhoyd/urlcode 0.4.2 → 0.4.7

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 (214) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +57 -14
  2. package/.claude/skills/urlcode-operations/SKILL.md +4 -0
  3. package/README.md +42 -18
  4. package/SECURITY.md +5 -3
  5. package/dist/BUILD-MANIFEST.json +30 -27
  6. package/dist/agent-context.js +82 -0
  7. package/dist/agents-guide.js +42 -42
  8. package/dist/authoring.js +12 -2
  9. package/dist/body-schema.js +159 -0
  10. package/dist/build-cloudflare.js +2 -0
  11. package/dist/capabilities.js +1 -1
  12. package/dist/cli.js +28 -12
  13. package/dist/config.js +74 -6
  14. package/dist/context.js +4 -6
  15. package/dist/errors.js +3 -1
  16. package/dist/examples.js +1 -1
  17. package/dist/extensions.js +60 -2
  18. package/dist/http-policy.js +19 -4
  19. package/dist/http-response.js +2 -2
  20. package/dist/init-with.js +71 -9
  21. package/dist/mcp.js +15 -2
  22. package/dist/pattern-guard.js +32 -0
  23. package/dist/policies/security.js +0 -0
  24. package/dist/project-tests.js +35 -11
  25. package/dist/readiness.js +184 -32
  26. package/dist/recipes.js +1 -1
  27. package/dist/router.js +17 -0
  28. package/dist/runtime.js +26 -3
  29. package/dist/scaffold.js +0 -0
  30. package/dist/server.js +26 -3
  31. package/dist/site.js +0 -0
  32. package/dist/tooling.js +2 -1
  33. package/dist/types/agent-context.d.ts +44 -0
  34. package/dist/types/authoring.d.ts +3 -1
  35. package/dist/types/body-schema.d.ts +58 -0
  36. package/dist/types/config.d.ts +10 -2
  37. package/dist/types/context.d.ts +1 -1
  38. package/dist/types/errors.d.ts +9 -1
  39. package/dist/types/examples.d.ts +1 -1
  40. package/dist/types/extensions.d.ts +47 -2
  41. package/dist/types/http-policy.d.ts +3 -0
  42. package/dist/types/init-with.d.ts +10 -1
  43. package/dist/types/pattern-guard.d.ts +10 -0
  44. package/dist/types/project-tests.d.ts +9 -0
  45. package/dist/types/readiness.d.ts +68 -0
  46. package/dist/types/recipes.d.ts +1 -1
  47. package/dist/types/runtime.d.ts +4 -0
  48. package/dist/types/server.d.ts +9 -1
  49. package/dist/types/tooling.d.ts +1 -0
  50. package/dist/types/types.d.ts +13 -0
  51. package/dist/types.js +10 -2
  52. package/dist/typescript-authoring.js +5 -3
  53. package/dist/verify-deployment.js +16 -10
  54. package/examples/body-validation/README.md +16 -0
  55. package/examples/body-validation/example.yaml +17 -0
  56. package/examples/body-validation/tests/requests.json +15 -0
  57. package/examples/body-validation/urlcode.yaml +34 -0
  58. package/examples/coverage-waiver/README.md +8 -0
  59. package/examples/coverage-waiver/example.yaml +16 -0
  60. package/examples/coverage-waiver/functions/notes.mjs +2 -0
  61. package/examples/coverage-waiver/tests/requests.json +3 -0
  62. package/examples/coverage-waiver/urlcode.yaml +10 -0
  63. package/examples/data-dir/README.md +39 -0
  64. package/examples/data-dir/data/welcome.txt +1 -0
  65. package/examples/data-dir/example.yaml +22 -0
  66. package/examples/data-dir/functions/note.mjs +18 -0
  67. package/examples/data-dir/tests/requests.json +6 -0
  68. package/examples/data-dir/urlcode.yaml +6 -0
  69. package/examples/lifecycle/README.md +15 -0
  70. package/examples/lifecycle/example.yaml +19 -0
  71. package/examples/lifecycle/functions/notes.mjs +29 -0
  72. package/examples/lifecycle/tests/requests.json +12 -0
  73. package/examples/lifecycle/urlcode.yaml +29 -0
  74. package/examples/not-found/README.md +10 -0
  75. package/examples/not-found/example.yaml +17 -0
  76. package/examples/not-found/public/404.html +3 -0
  77. package/examples/not-found/public/index.html +3 -0
  78. package/examples/not-found/tests/requests.json +7 -0
  79. package/examples/not-found/urlcode.yaml +7 -0
  80. package/examples/shared-blocks/README.md +11 -0
  81. package/examples/shared-blocks/example.yaml +17 -0
  82. package/examples/shared-blocks/tests/requests.json +7 -0
  83. package/examples/shared-blocks/urlcode.yaml +37 -0
  84. package/llms-full.txt +364 -49
  85. package/llms.txt +44 -6
  86. package/package.json +15 -26
  87. package/recipes/static-page/README.md +9 -0
  88. package/recipes/static-page/public/index.html +11 -0
  89. package/recipes/static-page/recipe.yaml +21 -0
  90. package/recipes/static-page/tests/requests.json +22 -0
  91. package/recipes/static-page/urlcode.yaml +7 -0
  92. package/recipes/static-plus-api/README.md +6 -0
  93. package/recipes/static-plus-api/urlcode.yaml +4 -0
  94. package/recipes/store-crud/README.md +53 -0
  95. package/recipes/store-crud/recipe.yaml +31 -0
  96. package/recipes/store-crud/tests/requests.json +18 -0
  97. package/recipes/store-crud/urlcode.yaml +18 -0
  98. package/schemas/urlcode.schema.json +125 -60
  99. package/skills/urlcode/SKILL.md +47 -27
  100. package/starters/default/AGENTS.md +43 -43
  101. package/starters/page/README.md +14 -0
  102. package/starters/page/public/index.html +12 -0
  103. package/starters/page/tests/requests.json +17 -0
  104. package/starters/page/urlcode.yaml +6 -0
  105. package/.claude-plugin/marketplace.json +0 -18
  106. package/CONTRIBUTING.md +0 -148
  107. package/ROADMAP.md +0 -70
  108. package/docs/AI-AUTHORING.md +0 -339
  109. package/docs/ASSETS.md +0 -107
  110. package/docs/AUTH-BACKUP.md +0 -32
  111. package/docs/AWS.md +0 -86
  112. package/docs/BEST-PRACTICES.md +0 -276
  113. package/docs/BULK.md +0 -79
  114. package/docs/CAPABILITIES.md +0 -192
  115. package/docs/CAPACITY.md +0 -305
  116. package/docs/CI-FOLLOWUP-2026-09-19.md +0 -97
  117. package/docs/CI-RELEASE-AUDIT-2026-09-19.md +0 -322
  118. package/docs/CI.md +0 -147
  119. package/docs/CLOUDFLARE.md +0 -109
  120. package/docs/CODEBASE-AUDIT-2026-09-20.md +0 -284
  121. package/docs/COMPLIANCE.md +0 -239
  122. package/docs/COMPOSING-A-SITE.md +0 -287
  123. package/docs/CONDITIONS.md +0 -74
  124. package/docs/CONTAINER-PROMOTION.md +0 -74
  125. package/docs/DEPLOYMENT-CHECKS.md +0 -108
  126. package/docs/DEVELOPMENT-PIPELINE.md +0 -304
  127. package/docs/EGRESS.md +0 -125
  128. package/docs/EXTENSIONS.md +0 -403
  129. package/docs/FRAMEWORK.md +0 -217
  130. package/docs/FUNCTION-SECURITY.md +0 -251
  131. package/docs/HTTP.md +0 -129
  132. package/docs/INSTALL.md +0 -128
  133. package/docs/INTERCHANGE.md +0 -134
  134. package/docs/LOAD-TESTING.md +0 -91
  135. package/docs/LOCAL-DEVELOPMENT.md +0 -102
  136. package/docs/MIDDLEWARE-EXAMPLES.md +0 -75
  137. package/docs/MIDDLEWARE.md +0 -102
  138. package/docs/MONITORING.md +0 -115
  139. package/docs/OBSERVABILITY.md +0 -222
  140. package/docs/OPEN-DECISIONS.md +0 -149
  141. package/docs/OPERATIONAL-PROOF.md +0 -41
  142. package/docs/OPERATIONS.md +0 -201
  143. package/docs/ORGANIZATION.md +0 -135
  144. package/docs/PERFORMANCE.md +0 -72
  145. package/docs/PLUGINS.md +0 -271
  146. package/docs/POLICIES.md +0 -211
  147. package/docs/PRERENDER.md +0 -245
  148. package/docs/PROJECT-DIRECTION.md +0 -118
  149. package/docs/PROVIDER-VERIFICATION.md +0 -84
  150. package/docs/READINESS.md +0 -153
  151. package/docs/README.md +0 -93
  152. package/docs/RECIPES.md +0 -99
  153. package/docs/RELEASE-0.4.0-alpha.3.md +0 -50
  154. package/docs/RELEASE-0.4.1.md +0 -73
  155. package/docs/RELEASE-0.4.2.md +0 -30
  156. package/docs/RELEASE-READINESS.md +0 -146
  157. package/docs/RELEASE-SECURITY.md +0 -100
  158. package/docs/RESILIENCE.md +0 -161
  159. package/docs/ROUTING.md +0 -92
  160. package/docs/SANDBOX-REVIEW.md +0 -72
  161. package/docs/SCAFFOLDING.md +0 -70
  162. package/docs/SECURITY-AUDIT.md +0 -164
  163. package/docs/SITE.md +0 -150
  164. package/docs/SPECIFICATION.md +0 -359
  165. package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +0 -288
  166. package/docs/SPIKE-BUSINESS-SUITE.md +0 -1029
  167. package/docs/SPIKE-CORE-LAYERING.md +0 -368
  168. package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +0 -207
  169. package/docs/STANDARDS.md +0 -311
  170. package/docs/STARTERS.md +0 -83
  171. package/docs/STATIC.md +0 -105
  172. package/docs/TOOLING.md +0 -298
  173. package/docs/TUNNELS.md +0 -72
  174. package/docs/TYPESCRIPT-AUTHORING.md +0 -87
  175. package/docs/TYPESCRIPT.md +0 -123
  176. package/docs/VERCEL.md +0 -114
  177. package/docs/VERSION-ALIGNMENT.md +0 -88
  178. package/docs/YAML-GUIDE.md +0 -57
  179. package/docs/YAML-REFERENCE.md +0 -449
  180. package/docs/archive/2026-09-19/EXTENSION-IMPLEMENTATION.md +0 -68
  181. package/docs/archive/2026-09-19/MANAGEMENT-SECURITY.md +0 -102
  182. package/docs/archive/2026-09-19/NEXT-PHASE-PLAN.md +0 -108
  183. package/docs/archive/2026-09-19/NEXT-STEPS.md +0 -646
  184. package/docs/archive/2026-09-19/OPEN-DECISIONS.md +0 -277
  185. package/docs/archive/2026-09-19/RELEASE-SECURITY.md +0 -186
  186. package/docs/archive/2026-09-19/ROADMAP.md +0 -387
  187. package/docs/archive/2026-09-19/SPIKE-EXTENSION-MODEL.md +0 -430
  188. package/docs/archive/2026-09-19/SPIKE-EXTENSIONS.md +0 -492
  189. package/docs/archive/2026-09-19/SPIKE-LAMBDA-COMPILE.md +0 -365
  190. package/docs/archive/2026-09-19/SPIKE-MONOREPO.md +0 -778
  191. package/docs/archive/2026-09-19/USABILITY-REVIEW.md +0 -139
  192. package/docs/archive/2026-09-20/OPEN-DECISIONS-COMPLETED.md +0 -116
  193. package/docs/archive/README.md +0 -29
  194. package/docs/policies/agents.md +0 -182
  195. package/docs/policies/cache.md +0 -152
  196. package/docs/policies/compression.md +0 -169
  197. package/docs/policies/contract.md +0 -52
  198. package/docs/policies/hardened.md +0 -56
  199. package/docs/policies/interoperability.md +0 -169
  200. package/docs/policies/operations.md +0 -45
  201. package/docs/policies/security.md +0 -161
  202. package/docs/policies/throttle.md +0 -103
  203. package/docs/yaml/assets.md +0 -36
  204. package/docs/yaml/conditions.md +0 -20
  205. package/docs/yaml/functions.md +0 -168
  206. package/docs/yaml/middleware.md +0 -31
  207. package/docs/yaml/organization.md +0 -74
  208. package/docs/yaml/policies.md +0 -37
  209. package/docs/yaml/redirects.md +0 -64
  210. package/docs/yaml/responses.md +0 -57
  211. package/docs/yaml/site.md +0 -24
  212. package/packaging/claude-plugin/.claude-plugin/plugin.json +0 -19
  213. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +0 -130
  214. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +0 -108
package/docs/VERCEL.md DELETED
@@ -1,114 +0,0 @@
1
- # Deploying to Vercel
2
-
3
- The Vercel adapter runs a URLCode project as a Node function. The same
4
- `urlcode.yaml` that runs locally or in a container serves the deployment —
5
- that is the point of the project format.
6
-
7
- **This adapter serves native handlers only:** redirects, validated responses,
8
- pages, static assets and downloads. `function` and `middleware` routes are
9
- refused at activation, trusted or sandboxed alike, not per request, so a deployment cannot
10
- half-work, and that is a settled position rather than a pending limitation. See
11
- [what is not supported](#what-this-adapter-does-not-do).
12
-
13
- A working project is in [`examples/vercel/`](../examples/vercel/).
14
-
15
- ## Set it up
16
-
17
- ```js
18
- // api/index.js
19
- import { createVercelHandler } from '@jimhoyd/urlcode/vercel';
20
-
21
- export default createVercelHandler({ project: process.cwd() });
22
- ```
23
-
24
- ```json
25
- {
26
- "functions": {
27
- "api/index.js": {
28
- "runtime": "nodejs22.x",
29
- "includeFiles": "{urlcode.yaml,routes/**,public/**}"
30
- }
31
- },
32
- "rewrites": [{ "source": "/(.*)", "destination": "/api" }]
33
- }
34
- ```
35
-
36
- Two details decide whether this works:
37
-
38
- - **`includeFiles`** must cover every file the project reads: the entry YAML,
39
- any `includes`, and every page, download and static directory. They are read
40
- at activation, so a missing one fails the whole deployment rather than one
41
- route. Node 22.13 or newer is required.
42
- - **The rewrite** sends every path to the handler, because URLCode owns routing.
43
- Anything you leave outside it is served by Vercel, not by your project.
44
-
45
- ## Bindings
46
-
47
- A self-hosted deployment grants `env` and `secrets` through an operator policy
48
- file outside the project. Vercel has no such place, so the adapter reads the
49
- same document from the **`URLCODE_POLICY`** environment variable:
50
-
51
- ```sh
52
- urlcode permissions --project . # prints the grant document
53
- vercel env add URLCODE_POLICY # paste it
54
- ```
55
-
56
- It is validated exactly as the file is, including the `projectSha256` pin — so a
57
- policy issued for one revision does not activate another. Change a route or a
58
- binding and the grant must be reissued, which is the intended friction. The
59
- values themselves are ordinary Vercel environment variables; the policy decides
60
- which routes may read them.
61
-
62
- ## Origin
63
-
64
- Functions and absolute URLs see the origin the adapter resolves, in order:
65
- the `origin` option, `URLCODE_ORIGIN`, then Vercel's own
66
- `VERCEL_PROJECT_PRODUCTION_URL`, `VERCEL_URL` or `VERCEL_BRANCH_URL`. Those are
67
- platform-set, not client-supplied — forwarded headers stay untrusted here as
68
- everywhere else. Set `URLCODE_ORIGIN` explicitly when you serve a custom domain
69
- and want it in generated URLs.
70
-
71
- ## What this adapter does not do
72
-
73
- | Not supported | Why |
74
- |---|---|
75
- | `function` routes | They need the self-hosted Node lifecycle; a `sandbox: true` route would additionally spawn worker threads and load the WASM engine on every cold start. Correctness is not the issue; the execution model is — per-route compilation was considered and declined. |
76
- | Middleware | Runs in the same execution mode as the route's function, and is refused with it. |
77
- | `urlcode serve` operational endpoints | `/_urlcode/health` and `/_urlcode/ready` describe a long-lived process. Use Vercel's own observability. |
78
-
79
- Each refusal happens at activation with a message naming the route, so you find
80
- out on deploy rather than on a request.
81
-
82
- `function` and `middleware` are not coming to this adapter. The supported answer
83
- is to deploy the project as one trusted Node process — a container or a VM
84
- running the project as it runs locally — which supports every route type today,
85
- on any host you like including AWS (ECS, EC2, App Runner). See
86
- [the decision](OPEN-DECISIONS.md#accepted-one-node-deployment-per-project) and
87
- [the analysis behind it](archive/2026-09-19/SPIKE-LAMBDA-COMPILE.md).
88
-
89
- ## Operating it
90
-
91
- Every instance activates the project independently: parsing YAML, snapshotting
92
- assets and compiling routes on each cold start. Keep asset snapshots small — the
93
- [capacity limits](CAPACITY.md) apply per instance, and a 64 MiB snapshot is 64
94
- MiB in every concurrent instance.
95
-
96
- There is no reload: a deployment serves the revision it was built from, which is
97
- what you want from immutable deployments. Ship a change by deploying.
98
-
99
- Logs go to Vercel's collector rather than to a stdout stream you control, so the
100
- [monitoring recipes](MONITORING.md) that parse JSON records need adapting;
101
- the record fields are the same.
102
-
103
- ## Verification status
104
-
105
- The adapter is tested against the self-hosted runtime for byte-identical status,
106
- body and headers across redirects, parameters, responses, pages, static files
107
- and misses, and for refusing unsupported handlers, enforcing the policy pin and
108
- bounding request bodies.
109
-
110
- **It has not been deployed to Vercel.** Those tests drive the real handler over
111
- a real Node request, which is the shape Vercel invokes, but no run on the
112
- platform has happened. Treat `includeFiles` coverage, cold-start latency and
113
- custom-domain behaviour as unverified until you deploy the example and see it
114
- work.
@@ -1,88 +0,0 @@
1
- # Package and channel alignment
2
-
3
- The package manifests and root lockfile are the version authority. Read live
4
- registry and Git tag state with `npm run release:status`; do not maintain a
5
- second table of changing version numbers in documentation.
6
-
7
- | Package | Manifest | Version owner | Release tag |
8
- | --- | --- | --- | --- |
9
- | `@jimhoyd/urlcode` | `package.json` | Explicit core release PR | `v<version>` |
10
- | `@jimhoyd/urlcode-ui` | `packages/ui/package.json` | Changesets | `@jimhoyd/urlcode-ui@<version>` |
11
- | `@jimhoyd/urlcode-auth` | `packages/auth/package.json` | Changesets | `@jimhoyd/urlcode-auth@<version>` |
12
- | `@jimhoyd/urlcode-admin` | `packages/admin/package.json` | Changesets | `@jimhoyd/urlcode-admin@<version>` |
13
-
14
- Development uses workspace source. Auth and admin's `file:../..` development
15
- links resolve core to this checkout, enforced by `check-workspace-links.ts`.
16
- Core never imports extension packages. Release verification instead installs the
17
- published lower bound of each declared peer range and checks resolution. A peer
18
- floor rises when code requires a newly introduced API, not just because a sibling
19
- published another version. Preserve the declared upper bound during Changesets
20
- versioning; `.changeset/config.json` limits unnecessary peer rewrites.
21
-
22
- Publishable workspace changes carry Changesets; the release PR applies them and
23
- updates versions, changelogs and the lockfile together. Core stays an explicit
24
- entry in that PR until a separately reviewed workspace migration. Its CLI banner
25
- must match its manifest. `npm run release:check` rejects stale lockfile versions.
26
- Unreleased source changes do not require moving a published tag or pretending a
27
- new package has already shipped.
28
-
29
- Manual GitHub Actions releases can select `core`, `ui`, `auth`, `admin`, or
30
- `all`. A single-package release updates only that package's manifest, lock entry,
31
- changelog and relevant Changesets; core also owns its duplicated CLI/MCP/plugin
32
- version metadata and downstream starter update. The all-packages action aligns
33
- every manifest and advances internal peer floors together. Changesets that name
34
- packages across the selected boundary must be released together rather than
35
- partially consumed.
36
-
37
- The `0.4.1` release is an explicit stable release decision for core, UI, auth
38
- and admin. Publication moves each package's npm `latest` channel to `0.4.1`, in
39
- core → UI → auth → admin order, after its release checks pass. A prepared
40
- manifest or merged release PR does not prove registry publication: use
41
- `npm run release:status` to inspect the live result before installing the set.
42
- This alignment does not permanently couple package versions; subsequent
43
- releases can still select only the packages that changed.
44
-
45
- Alpha releases publish under `alpha`; they never automatically move npm
46
- `latest`. Stable publication does not move `alpha`, so the two channels can
47
- legitimately show different versions. Test the install combination you recommend
48
- against peer ranges. `release:status` reports each declared peer floor and
49
- whether its current `latest` and `alpha` satisfy the range.
50
-
51
- After all four `0.4.1` versions are published, install the aligned set with:
52
-
53
- ```sh
54
- npm install --save-exact @jimhoyd/urlcode@0.4.1 @jimhoyd/urlcode-ui@0.4.1 @jimhoyd/urlcode-auth@0.4.1 @jimhoyd/urlcode-admin@0.4.1
55
- ```
56
-
57
- Bare package names resolve npm's current `latest`; exact application pins and a
58
- committed lockfile keep an existing application from changing on a new release.
59
-
60
- ## Generated applications
61
-
62
- A generated application records its own versions. `urlcode init --with` writes a
63
- `package.json` pinning the running runtime, the named extensions and their
64
- declared peers at the exact versions resolved at generation time, after checking
65
- that set against every declared peer range; `urlcode init --manifest` does the
66
- same for a route-only project with the runtime alone; `urlcode-auth init` pins
67
- this package and its peers. Plain `urlcode init` stays route-only and writes no
68
- manifest, for projects whose runtime is managed elsewhere. Generation never runs
69
- a package manager: `package-lock.json` exists only after the operator runs
70
- `npm install` in the generated directory, and a pin taken from a local path or
71
- tarball reproduces only where that path exists.
72
-
73
- No upgrade command exists. A generated project moves to new versions by an
74
- operator editing its manifest and re-installing. The issue that asked for this
75
- (#212) describes a future command that would choose a tested compatible set,
76
- show the changes and require explicit alpha selection; nothing here implements
77
- that, and the pins above are only the groundwork it would need.
78
-
79
- The standalone `urlcode-template` is an external exact-version consumer: after a
80
- runtime release, update its dependency and starter through its own reviewed PR.
81
- The coordinator prepares and checks that PR after registry installation succeeds;
82
- the template is a consumer update, not a fifth npm package. The retired
83
- `urlcode-docs`, `urlcode-middleware`, `urlcode-dynamic-link` and `urlcode-short`
84
- repositories are not release targets.
85
-
86
- See [the development pipeline](DEVELOPMENT-PIPELINE.md) for preparation,
87
- publication order, immutable retries and credential scope, and
88
- [release security](RELEASE-SECURITY.md) for provenance and limitations.
@@ -1,57 +0,0 @@
1
- # YAML guide and recipe book
2
-
3
- This guide targets URLCode 0.3.0. Start with the function example below,
4
- then add only the fields your route needs. The authoritative machine-readable
5
- shape is [JSON Schema](../schemas/urlcode.schema.json); semantic rules are in the
6
- [specification](SPECIFICATION.md). Unsupported fields fail validation.
7
-
8
- ## Run all the examples
9
-
10
- The [cookbook project](../examples/cookbook/urlcode.yaml) includes the six stateless handler
11
- types, middleware, typed/defaulted inputs, methods, response headers, body checks,
12
- expiry and file organization. Its referenced JavaScript and assets are included.
13
- From the runtime checkout:
14
-
15
- ```sh
16
- npm ci
17
- node src/cli.ts validate --project examples/cookbook
18
- node src/cli.ts test --project examples/cookbook
19
- node src/cli.ts audit --project examples/cookbook --expect-routes 40
20
- node src/cli.ts dev --project examples/cookbook
21
- ```
22
-
23
- The cookbook is a larger learning project. The normal `urlcode init ../my-links`
24
- remains a small two-route starter. For an independent application with a pinned
25
- runtime dependency, clone [urlcode-template](https://github.com/jimhoyd-com/urlcode-template).
26
-
27
- ## Pages
28
-
29
- Each page holds the recipes for one task; the section numbers continue across pages.
30
-
31
- | Page | Sections |
32
- |---|---|
33
- | [Functions, inputs and methods](yaml/functions.md) | 1. A URL that runs code; 4. Input types and constraints; 5. Methods and body validation; 6. All function argument sources |
34
- | [Redirects](yaml/redirects.md) | 2. Ordinary and permanent redirects; 3. Parameterized redirects and explicit query forwarding |
35
- | [Middleware](yaml/middleware.md) | 7. Middleware before and after a handler |
36
- | [Declared responses, headers and cookies](yaml/responses.md) | 8. Native responses, headers and cookies; 9. Explicit OPTIONS response (not automatic CORS) |
37
- | [Pages, static folders and downloads](yaml/assets.md) | 10. Pages, static folders, downloads and MIME |
38
- | [Enable, disable and expire](yaml/conditions.md) | 11. Enable, disable and expire |
39
- | [Bindings, split files and tests](yaml/organization.md) | 12. Environment and secret references; 13. Split files and folders; 14. Assert inputs and outputs |
40
- | [Policies and profiles](yaml/policies.md) | 16. Hardened profile and per-route overrides |
41
- | [Site conventions](yaml/site.md) | 17. Site conventions |
42
-
43
- ## Common mistakes
44
-
45
- | Mistake | Correction |
46
- |---|---|
47
- | Two handlers on one route | Choose exactly one; put reusable logic in middleware |
48
- | `/r/:id`, `/r/{id:.*}` or a regex | Use `/r/{id}` plus a required path input; no regex/greedy matching |
49
- | `${TOKEN}` or `process.env` | Use declared binding references and an external operator grant |
50
- | `fetch`, npm or Node imports | Unsupported in the guest; do not claim a network/storage integration |
51
- | Asset MIME/header overrides in `response.headers` | Configure `contentType`, `cacheControl`, `filename` on the asset handler |
52
- | `methods: [GET]` expecting HEAD | Declare HEAD too or omit methods for default GET/HEAD |
53
- | YAML fields for rate limits/workers/DNS/TLS | Deployment controls live outside portable route YAML |
54
- | YAML aliases, anchors or implicit date objects | Use plain JSON-compatible YAML and quoted timestamps |
55
- | Automatic hot updates in `serve` | Deploy/restart or use the embedding reload API deliberately |
56
- | “All examples are production-ready” | Validate your security, load and deployment requirements separately |
57
-