@jimhoyd/urlcode 0.3.0 → 0.4.0-alpha.1
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/.claude/skills/urlcode-authoring/SKILL.md +106 -0
- package/.claude/skills/urlcode-operations/SKILL.md +114 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/CONTRIBUTING.md +30 -2
- package/README.md +157 -230
- package/ROADMAP.md +85 -2
- package/SECURITY.md +8 -1
- package/dist/BUILD-MANIFEST.json +62 -32
- package/dist/adapters.js +4 -23
- package/dist/agent-lists.js +1 -1
- package/dist/agents-guide.js +113 -0
- package/dist/authoring-files.js +60 -0
- package/dist/authoring.js +11 -1
- package/dist/aws.js +4 -3
- package/dist/build-cloudflare.js +11 -24
- package/dist/bulk.js +37 -0
- package/dist/capabilities.js +208 -0
- package/dist/capability-query.js +72 -0
- package/dist/catalog.js +105 -0
- package/dist/cli.js +154 -15
- package/dist/client-address.js +1 -1
- package/dist/compliance-rules/baseline.js +8 -8
- package/dist/compliance-rules/privacy.js +3 -3
- package/dist/compliance-rules/strict.js +5 -5
- package/dist/conditions.js +88 -0
- package/dist/config.js +60 -4
- package/dist/context.js +156 -0
- package/dist/ecosystem-cli.js +88 -0
- package/dist/egress.js +98 -0
- package/dist/examples.js +92 -0
- package/dist/explain-cli.js +64 -0
- package/dist/explain.js +132 -0
- package/dist/extensions.js +172 -0
- package/dist/function-sources.js +15 -3
- package/dist/index.js +37 -0
- package/dist/init-with.js +165 -0
- package/dist/interchange-cli.js +42 -0
- package/dist/interchange.js +189 -0
- package/dist/link-cli.js +1 -1
- package/dist/management-policy.js +0 -1
- package/dist/manifest.js +111 -0
- package/dist/match.js +2 -2
- package/dist/mcp-authoring.js +147 -0
- package/dist/mcp.js +97 -0
- package/dist/observability.js +6 -0
- package/dist/operator-host.js +29 -0
- package/dist/plugins.js +12 -0
- package/dist/policies/agents.js +2 -2
- package/dist/policies/compression.js +2 -1
- package/dist/policies/security.js +0 -0
- package/dist/policies.js +1 -1
- package/dist/policy.js +29 -7
- package/dist/prerender.js +100 -41
- package/dist/project-tests.js +3 -3
- package/dist/provider-verification.js +92 -0
- package/dist/proxy.js +44 -0
- package/dist/readiness.js +5 -5
- package/dist/recipes.js +41 -0
- package/dist/route-diff.js +106 -0
- package/dist/router.js +42 -2
- package/dist/runtime.js +95 -14
- package/dist/schema-query.js +62 -0
- package/dist/signals.js +24 -0
- package/dist/site.js +0 -0
- package/dist/tooling.js +96 -0
- package/dist/types/adapters.d.ts +7 -4
- package/dist/types/agent-lists.d.ts +0 -1
- package/dist/types/agents-guide.d.ts +17 -0
- package/dist/types/authoring-files.d.ts +10 -0
- package/dist/types/aws.d.ts +3 -1
- package/dist/types/build-cloudflare.d.ts +1 -0
- package/dist/types/bulk.d.ts +27 -0
- package/dist/types/capabilities.d.ts +55 -0
- package/dist/types/capability-query.d.ts +24 -0
- package/dist/types/catalog.d.ts +65 -0
- package/dist/types/client-address.d.ts +0 -1
- package/dist/types/compliance-rules/baseline.d.ts +1 -9
- package/dist/types/compliance-rules/privacy.d.ts +1 -4
- package/dist/types/compliance-rules/strict.d.ts +0 -5
- package/dist/types/conditions.d.ts +19 -0
- package/dist/types/config.d.ts +20 -2
- package/dist/types/context.d.ts +65 -0
- package/dist/types/ecosystem-cli.d.ts +17 -0
- package/dist/types/egress.d.ts +46 -0
- package/dist/types/examples.d.ts +50 -0
- package/dist/types/explain-cli.d.ts +11 -0
- package/dist/types/explain.d.ts +95 -0
- package/dist/types/extensions.d.ts +122 -0
- package/dist/types/function-sources.d.ts +5 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/init-with.d.ts +30 -0
- package/dist/types/interchange-cli.d.ts +16 -0
- package/dist/types/interchange.d.ts +42 -0
- package/dist/types/link-cli.d.ts +2 -1
- package/dist/types/management-policy.d.ts +0 -1
- package/dist/types/manifest.d.ts +81 -0
- package/dist/types/match.d.ts +1 -0
- package/dist/types/mcp-authoring.d.ts +92 -0
- package/dist/types/mcp.d.ts +12 -0
- package/dist/types/observability.d.ts +2 -0
- package/dist/types/operator-host.d.ts +8 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/policies/agents.d.ts +0 -2
- package/dist/types/policies/compression.d.ts +2 -0
- package/dist/types/policies/security.d.ts +0 -1
- package/dist/types/policy.d.ts +15 -4
- package/dist/types/project-tests.d.ts +3 -1
- package/dist/types/provider-verification.d.ts +53 -0
- package/dist/types/proxy.d.ts +21 -0
- package/dist/types/readiness.d.ts +1 -1
- package/dist/types/recipes.d.ts +30 -0
- package/dist/types/route-diff.d.ts +27 -0
- package/dist/types/runtime.d.ts +11 -0
- package/dist/types/schema-query.d.ts +12 -0
- package/dist/types/signals.d.ts +25 -0
- package/dist/types/site.d.ts +0 -1
- package/dist/types/tooling.d.ts +115 -0
- package/dist/types/types.d.ts +57 -0
- package/dist/types/typescript-authoring.d.ts +12 -0
- package/dist/types/vercel.d.ts +3 -1
- package/dist/types/verify-deployment.d.ts +47 -0
- package/dist/types.js +21 -2
- package/dist/typescript-authoring.js +104 -0
- package/dist/vercel.js +4 -3
- package/dist/verify-deployment.js +270 -0
- package/docs/AI-AUTHORING.md +130 -8
- package/docs/BULK.md +79 -0
- package/docs/CAPABILITIES.md +179 -0
- package/docs/CAPACITY.md +1 -1
- package/docs/CI.md +142 -0
- package/docs/CONDITIONS.md +74 -0
- package/docs/DEPLOYMENT-CHECKS.md +108 -0
- package/docs/DYNAMIC-LINKS.md +18 -518
- package/docs/EGRESS.md +125 -0
- package/docs/EXTENSIONS.md +226 -0
- package/docs/FRAMEWORK.md +182 -0
- package/docs/INSTALL.md +45 -7
- package/docs/INTERCHANGE.md +134 -0
- package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
- package/docs/MIDDLEWARE.md +2 -0
- package/docs/NEXT-PHASE-PLAN.md +90 -0
- package/docs/NEXT-STEPS.md +415 -0
- package/docs/OBSERVABILITY.md +4 -2
- package/docs/OPERATIONAL-PROOF.md +4 -1
- package/docs/OPERATIONS.md +6 -3
- package/docs/PLUGINS.md +37 -0
- package/docs/POLICIES.md +12 -309
- package/docs/PRERENDER.md +40 -0
- package/docs/PROJECT-DIRECTION.md +42 -0
- package/docs/PROVIDER-VERIFICATION.md +84 -0
- package/docs/READINESS.md +21 -1
- package/docs/README.md +82 -31
- package/docs/RECIPES.md +99 -0
- package/docs/RELEASE-READINESS.md +11 -9
- package/docs/RELEASE-SECURITY.md +27 -4
- package/docs/SECURITY-AUDIT.md +1 -1
- package/docs/SPECIFICATION.md +95 -8
- package/docs/SPIKE-BUSINESS-SUITE.md +1013 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
- package/docs/SPIKE-EXTENSIONS.md +1 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +199 -0
- package/docs/STANDARDS.md +150 -142
- package/docs/STARTERS.md +21 -1
- package/docs/TOOLING.md +291 -0
- package/docs/TYPESCRIPT-AUTHORING.md +67 -0
- package/docs/TYPESCRIPT.md +1 -1
- package/docs/USABILITY-REVIEW.md +123 -0
- package/docs/YAML-GUIDE.md +18 -479
- package/docs/YAML-REFERENCE.md +127 -16
- package/docs/links/cli.md +110 -0
- package/docs/links/limits.md +175 -0
- package/docs/links/management-api.md +80 -0
- package/docs/links/pools.md +75 -0
- package/docs/links/setup.md +135 -0
- package/docs/policies/agents.md +1 -1
- package/docs/policies/contract.md +52 -0
- package/docs/policies/hardened.md +56 -0
- package/docs/policies/interoperability.md +169 -0
- package/docs/policies/operations.md +45 -0
- package/docs/yaml/assets.md +36 -0
- package/docs/yaml/conditions.md +20 -0
- package/docs/yaml/functions.md +160 -0
- package/docs/yaml/links.md +30 -0
- package/docs/yaml/middleware.md +29 -0
- package/docs/yaml/organization.md +74 -0
- package/docs/yaml/policies.md +37 -0
- package/docs/yaml/redirects.md +64 -0
- package/docs/yaml/responses.md +57 -0
- package/docs/yaml/site.md +24 -0
- package/examples/assets/example.yaml +17 -0
- package/examples/aws/example.yaml +20 -0
- package/examples/cloudflare/example.yaml +19 -0
- package/examples/compliance/example.yaml +11 -0
- package/examples/conditions/README.md +12 -0
- package/examples/conditions/example.yaml +19 -0
- package/examples/conditions/tests/requests.json +13 -0
- package/examples/conditions/urlcode.yaml +24 -0
- package/examples/cookbook/README.md +8 -4
- package/examples/cookbook/example.yaml +17 -0
- package/examples/cookbook/functions/catalog.mjs +3 -0
- package/examples/cookbook/functions/fail.mjs +4 -0
- package/examples/cookbook/functions/items.mjs +3 -0
- package/examples/cookbook/functions/profile.mjs +3 -0
- package/examples/cookbook/functions/resource.mjs +3 -0
- package/examples/cookbook/functions/status.mjs +3 -0
- package/examples/cookbook/middleware/auth.mjs +48 -0
- package/examples/cookbook/middleware/body.mjs +15 -0
- package/examples/cookbook/middleware/bucket.mjs +19 -0
- package/examples/cookbook/middleware/cors.mjs +21 -0
- package/examples/cookbook/middleware/debug.mjs +13 -0
- package/examples/cookbook/middleware/envelope.mjs +11 -0
- package/examples/cookbook/middleware/errors.mjs +11 -0
- package/examples/cookbook/middleware/etag.mjs +18 -0
- package/examples/cookbook/middleware/locale.mjs +16 -0
- package/examples/cookbook/middleware/maintenance.mjs +10 -0
- package/examples/cookbook/middleware/methods.mjs +15 -0
- package/examples/cookbook/middleware/negotiate.mjs +20 -0
- package/examples/cookbook/middleware/referer.mjs +12 -0
- package/examples/cookbook/middleware/request-id.mjs +16 -0
- package/examples/cookbook/route-index.json +676 -0
- package/examples/cookbook/routes/middleware.yaml +126 -0
- package/examples/cookbook/tests/requests.json +526 -0
- package/examples/cookbook/urlcode.yaml +1 -0
- package/examples/egress/README.md +22 -0
- package/examples/egress/example.yaml +19 -0
- package/examples/egress/urlcode.yaml +19 -0
- package/examples/extensions/README.md +7 -0
- package/examples/extensions/example.yaml +21 -0
- package/examples/extensions/urlcode.yaml +25 -0
- package/examples/live-links/example.yaml +21 -0
- package/examples/monitoring/example.yaml +8 -0
- package/examples/prerender/example.yaml +16 -0
- package/examples/provider-conformance/README.md +12 -0
- package/examples/provider-conformance/example.yaml +14 -0
- package/examples/provider-conformance/urlcode.yaml +34 -0
- package/examples/tunnel/example.yaml +8 -0
- package/examples/vercel/example.yaml +19 -0
- package/llms-full.txt +2709 -0
- package/llms.txt +48 -19
- package/package.json +29 -7
- package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +106 -0
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +114 -0
- package/recipes/authenticated-json-api/README.md +51 -0
- package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
- package/recipes/authenticated-json-api/recipe.yaml +34 -0
- package/recipes/authenticated-json-api/tests/requests.json +39 -0
- package/recipes/authenticated-json-api/urlcode.yaml +12 -0
- package/recipes/contact-form/README.md +25 -0
- package/recipes/contact-form/functions/contact.mjs +17 -0
- package/recipes/contact-form/recipe.yaml +33 -0
- package/recipes/contact-form/tests/requests.json +47 -0
- package/recipes/contact-form/urlcode.yaml +18 -0
- package/recipes/cors-api/README.md +16 -0
- package/recipes/cors-api/functions/items.mjs +3 -0
- package/recipes/cors-api/middleware/cors.mjs +21 -0
- package/recipes/cors-api/recipe.yaml +26 -0
- package/recipes/cors-api/tests/requests.json +65 -0
- package/recipes/cors-api/urlcode.yaml +12 -0
- package/recipes/health-page/README.md +13 -0
- package/recipes/health-page/recipe.yaml +23 -0
- package/recipes/health-page/tests/requests.json +36 -0
- package/recipes/health-page/urlcode.yaml +19 -0
- package/recipes/json-api/README.md +6 -0
- package/recipes/json-api/functions/echo.mjs +3 -0
- package/recipes/json-api/recipe.yaml +25 -0
- package/recipes/json-api/tests/requests.json +34 -0
- package/recipes/json-api/urlcode.yaml +12 -0
- package/recipes/middleware/README.md +34 -0
- package/recipes/middleware/functions/catalog.mjs +3 -0
- package/recipes/middleware/functions/fail.mjs +4 -0
- package/recipes/middleware/functions/items.mjs +3 -0
- package/recipes/middleware/functions/profile.mjs +3 -0
- package/recipes/middleware/functions/resource.mjs +3 -0
- package/recipes/middleware/functions/status.mjs +3 -0
- package/recipes/middleware/middleware/auth.mjs +48 -0
- package/recipes/middleware/middleware/body.mjs +15 -0
- package/recipes/middleware/middleware/bucket.mjs +19 -0
- package/recipes/middleware/middleware/cors.mjs +21 -0
- package/recipes/middleware/middleware/debug.mjs +13 -0
- package/recipes/middleware/middleware/envelope.mjs +11 -0
- package/recipes/middleware/middleware/errors.mjs +11 -0
- package/recipes/middleware/middleware/etag.mjs +18 -0
- package/recipes/middleware/middleware/locale.mjs +16 -0
- package/recipes/middleware/middleware/maintenance.mjs +10 -0
- package/recipes/middleware/middleware/methods.mjs +15 -0
- package/recipes/middleware/middleware/negotiate.mjs +20 -0
- package/recipes/middleware/middleware/referer.mjs +12 -0
- package/recipes/middleware/middleware/request-id.mjs +16 -0
- package/recipes/middleware/public/guide.txt +1 -0
- package/recipes/middleware/recipe.yaml +50 -0
- package/recipes/middleware/tests/requests.json +528 -0
- package/recipes/middleware/urlcode.yaml +127 -0
- package/recipes/protected-download/README.md +22 -0
- package/recipes/protected-download/files/report.txt +1 -0
- package/recipes/protected-download/recipe.yaml +31 -0
- package/recipes/protected-download/tests/requests.json +32 -0
- package/recipes/protected-download/urlcode.yaml +15 -0
- package/recipes/redirect/README.md +7 -0
- package/recipes/redirect/recipe.yaml +25 -0
- package/recipes/redirect/tests/requests.json +19 -0
- package/recipes/redirect/urlcode.yaml +9 -0
- package/recipes/static-plus-api/README.md +15 -0
- package/recipes/static-plus-api/functions/info.mjs +3 -0
- package/recipes/static-plus-api/public/assets/index.html +3 -0
- package/recipes/static-plus-api/public/assets/site.css +1 -0
- package/recipes/static-plus-api/public/index.html +8 -0
- package/recipes/static-plus-api/recipe.yaml +29 -0
- package/recipes/static-plus-api/tests/requests.json +56 -0
- package/recipes/static-plus-api/urlcode.yaml +23 -0
- package/recipes/typescript/README.md +7 -0
- package/recipes/typescript/functions/hello.ts +5 -0
- package/recipes/typescript/recipe.yaml +23 -0
- package/recipes/typescript/tests/requests.json +18 -0
- package/recipes/typescript/urlcode.yaml +5 -0
- package/recipes/webhook-receiver/README.md +16 -0
- package/recipes/webhook-receiver/functions/receive.mjs +16 -0
- package/recipes/webhook-receiver/recipe.yaml +26 -0
- package/recipes/webhook-receiver/tests/requests.json +59 -0
- package/recipes/webhook-receiver/urlcode.yaml +16 -0
- package/schemas/recipe.schema.json +138 -0
- package/schemas/urlcode.schema.json +656 -80
- package/skills/urlcode/SKILL.md +98 -0
- package/starters/default/.github/workflows/urlcode.yml +23 -0
- package/starters/default/.mcp.json +12 -0
- package/starters/default/AGENTS.md +79 -0
package/docs/README.md
CHANGED
|
@@ -1,58 +1,109 @@
|
|
|
1
1
|
# URLCode documentation
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
> **Public documentation has moved to
|
|
4
|
+
> [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs).** That repository
|
|
5
|
+
> is the documentation home and is authored directly — this tree is no longer
|
|
6
|
+
> mirrored into it. New reader-facing pages belong in urlcode-docs; `docs/` here
|
|
7
|
+
> keeps contributor and maintainer material (local development, CI, release
|
|
8
|
+
> process, reviews, spikes, plans and the generated field reference). The
|
|
9
|
+
> reader-facing pages still listed below are being migrated.
|
|
5
10
|
|
|
6
|
-
|
|
11
|
+
Start with [the framework](FRAMEWORK.md): the four packages, the ladder from
|
|
12
|
+
redirects to a full application, the composition contract and the rules an AI
|
|
13
|
+
agent must follow. [Project direction](PROJECT-DIRECTION.md) states the
|
|
14
|
+
boundary and the license. Use documentation pinned to your runtime revision;
|
|
7
15
|
`version: "1"` is the stable project-format contract for this release line.
|
|
8
16
|
|
|
17
|
+
## Author a project
|
|
18
|
+
|
|
9
19
|
| Goal | Start here |
|
|
10
20
|
|---|---|
|
|
11
21
|
| Install the CLI | [Installation](INSTALL.md) |
|
|
12
|
-
| Generate placeholders from YAML | [Scaffolding](SCAFFOLDING.md) |
|
|
13
22
|
| Write YAML with examples | [YAML guide and recipes](YAML-GUIDE.md) |
|
|
14
23
|
| Look up every accepted field | [Generated field reference](YAML-REFERENCE.md), [JSON Schema](../schemas/urlcode.schema.json) |
|
|
15
24
|
| Let an AI build routes | [AI authoring guide](AI-AUTHORING.md), [llms.txt](../llms.txt) |
|
|
25
|
+
| Load authoring/operations rules into an agent | [Authoring skill](../.claude/skills/urlcode-authoring/SKILL.md), [operations skill](../.claude/skills/urlcode-operations/SKILL.md), [how they are distributed](AI-AUTHORING.md#agent-skills) |
|
|
16
26
|
| Run examples | [25-route cookbook](../examples/cookbook/README.md), [prerender recipe](../examples/prerender/README.md), [small starter](STARTERS.md) |
|
|
17
27
|
| Explore a standalone application | [URLCode Shortener demo](https://github.com/jimhoyd-com/urlcode-shortener), [build retrospective](https://github.com/jimhoyd-com/urlcode-shortener/blob/main/docs/BUILD-RETROSPECTIVE.md) |
|
|
18
28
|
| Explore a static docs-site integration | [URLCode Docs project](https://github.com/jimhoyd-com/urlcode-docs), [build retrospective](https://github.com/jimhoyd-com/urlcode-docs/blob/main/docs/BUILD-RETROSPECTIVE.md) — synced from this repository, which remains the source of truth |
|
|
19
29
|
| Create/update short links live | [Dynamic links, storage and management API](DYNAMIC-LINKS.md) |
|
|
20
30
|
| Understand exact behavior | [Specification](SPECIFICATION.md), [routing](ROUTING.md), [HTTP](HTTP.md) |
|
|
21
|
-
|
|
|
22
|
-
|
|
|
31
|
+
| Run examples | [40-route cookbook](../examples/cookbook/README.md), [prerender recipe](../examples/prerender/README.md), [small starter](STARTERS.md) |
|
|
32
|
+
| Let an AI build routes | [The framework](FRAMEWORK.md), [AI authoring guide](AI-AUTHORING.md), [llms.txt](../llms.txt), [SDK and read-only MCP](TOOLING.md) |
|
|
33
|
+
| Reuse code around routes | [Middleware](MIDDLEWARE.md), [middleware examples](MIDDLEWARE-EXAMPLES.md) |
|
|
34
|
+
| Handle secrets and untrusted code | [Function security](FUNCTION-SECURITY.md) |
|
|
35
|
+
| Author guest functions in TypeScript | [Build-time guest transpilation](TYPESCRIPT-AUTHORING.md) |
|
|
36
|
+
| Serve pages, files and downloads | [Assets](ASSETS.md) |
|
|
37
|
+
| Publish a site with no request-time guest code | [Prerendering helper and recipe](PRERENDER.md) |
|
|
38
|
+
| Create and update short links live | [Dynamic links, storage and management API](DYNAMIC-LINKS.md) |
|
|
39
|
+
| Select response branches | [Exact conditions](CONDITIONS.md) |
|
|
40
|
+
| Proxy an API or emit a webhook | [Bounded egress and operator grants](EGRESS.md) |
|
|
41
|
+
| Throttle, block agents, set security headers, compress or cache | [Policies](POLICIES.md): [throttle](policies/throttle.md), [agents](policies/agents.md), [security](policies/security.md), [compression](policies/compression.md), [cache](policies/cache.md) |
|
|
42
|
+
| Generate robots.txt, sitemap.xml, favicon, security.txt and llms.txt | [Site conventions](SITE.md) |
|
|
43
|
+
| Organize YAML across folders | [Organization](ORGANIZATION.md), [readability practices](BEST-PRACTICES.md) |
|
|
44
|
+
| Generate placeholders from YAML | [Scaffolding](SCAFFOLDING.md) |
|
|
45
|
+
| Convert provider redirect files | [Strict interchange and conversion reports](INTERCHANGE.md) |
|
|
46
|
+
| Import thousands of redirects | [Bulk import and scale evidence](BULK.md) |
|
|
47
|
+
| Reuse local project recipes | [Recipe catalog](RECIPES.md) |
|
|
48
|
+
| Check declared configuration against standards-referenced rules | [Compliance](COMPLIANCE.md) |
|
|
49
|
+
|
|
50
|
+
## Extend the runtime
|
|
51
|
+
|
|
52
|
+
| Goal | Start here |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Add accounts, sign-in and protected routes | [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth#readme) |
|
|
55
|
+
| Manage users, sessions, roles and audit | [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin#readme) |
|
|
56
|
+
| Restyle every extension page and translate copy | [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui#readme), [ui contract](https://github.com/jimhoyd-com/urlcode-ui/blob/main/CONTRACT.md) |
|
|
57
|
+
| Write or install a versioned extension | [Extensions](EXTENSIONS.md), [example fixture](../examples/extensions/README.md) |
|
|
23
58
|
| Add host behavior in operator code | [Plugins](PLUGINS.md) |
|
|
24
59
|
| Use the API from TypeScript | [TypeScript: shipped declarations, exports, build and fidelity](TYPESCRIPT.md) |
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
| Organize YAML across folders | [Organization](ORGANIZATION.md) |
|
|
32
|
-
| Work locally | [Local development](LOCAL-DEVELOPMENT.md) |
|
|
33
|
-
| Share a local project publicly | [Tunnels](TUNNELS.md) |
|
|
34
|
-
| Watch a deployment | [Monitoring](MONITORING.md) |
|
|
35
|
-
| Wire your own monitoring or scrape metrics | [Observability](OBSERVABILITY.md) |
|
|
36
|
-
| Load test a deployment | [Load testing](LOAD-TESTING.md) |
|
|
37
|
-
| Deploy to Vercel | [Vercel adapter](VERCEL.md) |
|
|
38
|
-
| Deploy to AWS Lambda | [AWS adapter](AWS.md) |
|
|
39
|
-
| Deploy to Cloudflare Workers | [Cloudflare target](CLOUDFLARE.md) |
|
|
40
|
-
| Handle secrets/untrusted code | [Function security](FUNCTION-SECURITY.md) |
|
|
60
|
+
|
|
61
|
+
## Operate and deploy
|
|
62
|
+
|
|
63
|
+
| Goal | Start here |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Work locally | [Local development](LOCAL-DEVELOPMENT.md), [tunnels](TUNNELS.md) |
|
|
41
66
|
| Prove responses and counts | [Readiness](READINESS.md) |
|
|
42
|
-
|
|
|
43
|
-
| Prepare for overload/DDoS/recovery | [Resilience playbook](RESILIENCE.md) |
|
|
67
|
+
| Check pull requests of a project on GitHub | [CI action, route diffs and the starter workflow](CI.md) |
|
|
44
68
|
| Deploy and roll back | [Operations](OPERATIONS.md) |
|
|
45
69
|
| Review security findings and gaps | [Internal security audit](SECURITY-AUDIT.md) |
|
|
46
70
|
| Assess release readiness | [Evidence and open gates](RELEASE-READINESS.md) |
|
|
47
71
|
| See unfinished work | [Roadmap](../ROADMAP.md) |
|
|
48
72
|
| Read the design behind policies, plugins and templates | [Extensions spike](SPIKE-EXTENSIONS.md) |
|
|
73
|
+
| Read the design for an authentication and authorization plugin | [Auth spike](SPIKE-AUTH.md) |
|
|
74
|
+
| Read the design for the administration extension that manages users | [Admin spike](SPIKE-ADMIN.md) |
|
|
75
|
+
| Read the design for the shared template kit every extension renders with | [UI kit spike](SPIKE-UI.md) |
|
|
76
|
+
| Read the review of the extension model, its precedents and alignment | [Extension model review](SPIKE-EXTENSION-MODEL.md) |
|
|
77
|
+
| Read the design for compiling function routes into per-route Lambdas | [Lambda compile spike](SPIKE-LAMBDA-COMPILE.md) |
|
|
78
|
+
| Verify a running deployment matches the project | [Deployment checks](DEPLOYMENT-CHECKS.md) |
|
|
79
|
+
| Inspect target support | [Capabilities and normalized representation](CAPABILITIES.md) |
|
|
80
|
+
| Deploy to Vercel, AWS Lambda or Cloudflare Workers | [Vercel](VERCEL.md), [AWS](AWS.md), [Cloudflare](CLOUDFLARE.md), [provider verification evidence](PROVIDER-VERIFICATION.md) |
|
|
81
|
+
| Watch a deployment | [Monitoring](MONITORING.md), [observability](OBSERVABILITY.md) |
|
|
82
|
+
| Estimate concurrency and memory | [Capacity and limits](CAPACITY.md), [measurements](PERFORMANCE.md), [load testing](LOAD-TESTING.md) |
|
|
83
|
+
| Prepare for overload, DDoS and recovery | [Resilience playbook](RESILIENCE.md) |
|
|
84
|
+
| Manage private credentials and audit | [Management security](MANAGEMENT-SECURITY.md) |
|
|
49
85
|
|
|
50
|
-
|
|
51
|
-
Infrastructure limits are deployment settings, not fields to invent in route YAML.
|
|
86
|
+
## Evidence, reviews and design records
|
|
52
87
|
|
|
53
|
-
|
|
88
|
+
These are dated records, not guides. They say what has been checked and what
|
|
89
|
+
has not, and why the design is the way it is.
|
|
54
90
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
91
|
+
| Record | What it is |
|
|
92
|
+
|---|---|
|
|
93
|
+
| [Release readiness](RELEASE-READINESS.md) | Verified safeguards, open gates, supported scope |
|
|
94
|
+
| [Usability review](USABILITY-REVIEW.md) | Where the framework is easier or harder than the tools it replaces, and ranked changes |
|
|
95
|
+
| [Next steps](NEXT-STEPS.md) | The phased plan: agent discovery, context compression, retrieval, the ladder, benchmarks and the remaining proof gaps |
|
|
96
|
+
| [Next-phase implementation status](NEXT-PHASE-PLAN.md) | Source additions after 0.3.0 shipped in 0.4.0-alpha.1, and their evidence limits |
|
|
97
|
+
| [Security review](SECURITY-AUDIT.md) | Internal findings and fixes; not an independent test |
|
|
98
|
+
| [Standards audit](STANDARDS.md) | How the runtime conforms to the RFCs it touches |
|
|
99
|
+
| [Sandbox review package](SANDBOX-REVIEW.md) | What an independent reviewer needs; assessment not yet performed |
|
|
100
|
+
| [Operational drills](OPERATIONAL-PROOF.md) | Deployment acceptance drills CI runs |
|
|
101
|
+
| [Release security](RELEASE-SECURITY.md) | Candidate signing and publication process |
|
|
102
|
+
| [Extension model review](SPIKE-EXTENSION-MODEL.md) | Why extensions are shaped this way, with framework precedents |
|
|
103
|
+
| [Extensions spike](SPIKE-EXTENSIONS.md) | The design behind policies and plugins; implemented |
|
|
104
|
+
| [Lambda compile spike](SPIKE-LAMBDA-COMPILE.md) | Proposal: per-route Lambdas for functions; not implemented |
|
|
105
|
+
| Auth, admin and UI spikes | Live in their repositories: [auth](https://github.com/jimhoyd-com/urlcode-auth/blob/main/docs/SPIKE-AUTH.md), [admin](https://github.com/jimhoyd-com/urlcode-admin/blob/main/docs/SPIKE-ADMIN.md), [ui](https://github.com/jimhoyd-com/urlcode-ui/blob/main/docs/SPIKE-UI.md) |
|
|
106
|
+
| [Roadmap](../ROADMAP.md) | Implemented versus planned |
|
|
107
|
+
|
|
108
|
+
Examples are educational unless backed by the runnable cookbook and fixtures.
|
|
109
|
+
Infrastructure limits are deployment settings, not fields to invent in route YAML.
|
package/docs/RECIPES.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Local recipes
|
|
2
|
+
|
|
3
|
+
Recipes are ordinary version-controlled URLCode projects shipped with the
|
|
4
|
+
runtime. There is no network registry, install script, provider account or
|
|
5
|
+
project-code execution during authoring. Search them before writing a common
|
|
6
|
+
route by hand: the catalog is the vocabulary of behavior the runtime already
|
|
7
|
+
supports, and every recipe validates, tests and audits.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
urlcode recipes list
|
|
11
|
+
urlcode recipes search "webhook json" # id, description, tags, capabilities
|
|
12
|
+
urlcode recipes search webhook --json
|
|
13
|
+
urlcode recipes show webhook-receiver # metadata first, then every file
|
|
14
|
+
urlcode recipes add webhook-receiver --out ./orders-hook --dry-run
|
|
15
|
+
urlcode recipes add webhook-receiver --out ./orders-hook
|
|
16
|
+
urlcode validate --local --project ./orders-hook
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## The catalog
|
|
20
|
+
|
|
21
|
+
| Recipe | Complexity | What it shows | Needs |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `redirect` | starter | Permanent redirect forwarding one allowlisted query key | nothing |
|
|
24
|
+
| `health-page` | starter | Native `/health` text and `/status` JSON, no-store | nothing |
|
|
25
|
+
| `json-api` | starter | Bounded JSON body echoed by a sandboxed function | self-hosted runtime |
|
|
26
|
+
| `webhook-receiver` | starter | JSON event with a type header, shape-checked, `202` | self-hosted runtime |
|
|
27
|
+
| `typescript` | intermediate | Typed guest transpiled by `build-typescript` | build step |
|
|
28
|
+
| `static-plus-api` | intermediate | Page, static directory and one JSON function | self-hosted runtime |
|
|
29
|
+
| `cors-api` | intermediate | Preflight and CORS headers from route middleware | self-hosted runtime |
|
|
30
|
+
| `contact-form` | intermediate | Validated message, fixed signal to a hook after the response | signal grant (`--policy`) |
|
|
31
|
+
| `middleware` | advanced | Fourteen reusable middleware patterns ([described here](MIDDLEWARE-EXAMPLES.md)) | self-hosted runtime |
|
|
32
|
+
| `authenticated-json-api` | advanced | Function behind `auth: true` | operator auth extension, `--host-file`, `--origin` |
|
|
33
|
+
| `protected-download` | advanced | Native attachment behind `auth: true` | operator auth extension, `--host-file`, `--origin` |
|
|
34
|
+
|
|
35
|
+
Each recipe contains a README, `tests/requests.json` and editable files.
|
|
36
|
+
Replace example destinations and review the resulting files before use. The
|
|
37
|
+
authenticated recipes declare `extensions.auth` and protect their route with
|
|
38
|
+
the short form described in [extensions](EXTENSIONS.md); their README shows the
|
|
39
|
+
minimal host-file fixture that reproduces the bundled tests. Nothing in the
|
|
40
|
+
catalog verifies webhook signatures: the sandbox has no crypto or network API,
|
|
41
|
+
so signed webhooks belong behind an operator extension or a trusted host.
|
|
42
|
+
|
|
43
|
+
## `recipe.yaml`
|
|
44
|
+
|
|
45
|
+
Every recipe carries `recipe.yaml`, validated against
|
|
46
|
+
[`schemas/recipe.schema.json`](../schemas/recipe.schema.json) by `npm run check`:
|
|
47
|
+
|
|
48
|
+
- `id`, `description`, `tags`, `complexity` (`starter`, `intermediate`,
|
|
49
|
+
`advanced`): written by hand; `search` matches id, description, tags and
|
|
50
|
+
capabilities, every word must match, and whole-tag or id hits rank first.
|
|
51
|
+
- `capabilities`, `targets`, `routes`: derived from the capability preflight
|
|
52
|
+
(`analyzeProjectCapabilities` per target after site expansion). The check
|
|
53
|
+
refuses a hand-edited value that differs, so a recipe cannot claim a target
|
|
54
|
+
it does not activate on. `targets` is `compatible`, or the strongest issue
|
|
55
|
+
(`conditional`, `unknown`, `refused`); `routes` is the `--expect-routes` value.
|
|
56
|
+
- `services` (external services), `grants` (operator grants, never from project
|
|
57
|
+
files), `inputs` (what to edit), `files` (the copy list), `tests` (fixtures
|
|
58
|
+
and the exact commands) and `behavior` (one observable statement per line).
|
|
59
|
+
|
|
60
|
+
`show` prints this metadata before the file contents so a reader sees what a
|
|
61
|
+
recipe needs before its files scroll past; `--json` returns the same object with
|
|
62
|
+
a `content` map. `list` prints one line per recipe, or the metadata with `--json`.
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
`examples/*/example.yaml` uses the same schema, and `urlcode examples search
|
|
67
|
+
<text> [--json]` returns the smallest matching runnable example first with the
|
|
68
|
+
file to read. The cookbook's forty routes are indexed per route in the generated
|
|
69
|
+
[`examples/cookbook/route-index.json`](../examples/cookbook/route-index.json)
|
|
70
|
+
(handler, methods, capabilities, policies and middleware module names as tags;
|
|
71
|
+
`npm run docs:cookbook-index` regenerates it and `npm run check` refuses a stale
|
|
72
|
+
copy), so a search for `etag` answers the cookbook and its `/versioned` route.
|
|
73
|
+
Entries without a `urlcode.yaml` (operator rules, monitoring configuration,
|
|
74
|
+
scripts) are `runnable: false` and carry no derived fields.
|
|
75
|
+
|
|
76
|
+
## Adding a recipe
|
|
77
|
+
|
|
78
|
+
`add` creates a new standalone directory. It refuses an existing destination,
|
|
79
|
+
even an empty directory; it never merges or overwrites existing project routes.
|
|
80
|
+
Review or copy selected declarations manually when combining projects. Dry-run
|
|
81
|
+
reads and validates the packaged recipe and checks the destination, but writes
|
|
82
|
+
nothing. The output parent must already exist and be owned by the caller.
|
|
83
|
+
Dependencies are written first and the complete `urlcode.yaml` is published by
|
|
84
|
+
rename last. A failed write removes the new directory. This is atomic project
|
|
85
|
+
activation, not an atomic directory replacement or a guarantee against a local
|
|
86
|
+
attacker concurrently replacing the caller's output directories.
|
|
87
|
+
|
|
88
|
+
## SDK and MCP
|
|
89
|
+
|
|
90
|
+
The SDK provides `listRecipes()`, `searchRecipes(text)`, `showRecipe(name)`,
|
|
91
|
+
`addRecipe(name, output, {dryRun})`, `listExamples()` and `searchExamples(text)`.
|
|
92
|
+
Catalog names are a fixed list in code; metadata and file lists come from each
|
|
93
|
+
schema-checked `recipe.yaml` and are returned as copies. Unknown names and
|
|
94
|
+
arbitrary paths/URLs fail closed. The stdio MCP server adds `search_recipes` and
|
|
95
|
+
`search_examples` beside `recipes_list` and `recipes_show`
|
|
96
|
+
([tooling](TOOLING.md)). Integration tests run every recipe through the real
|
|
97
|
+
runtime with its fixtures and audit it with its declared route count (after
|
|
98
|
+
building the TypeScript recipe, with a fixture registry for the authenticated
|
|
99
|
+
ones and the generated policy for the contact form).
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Release readiness
|
|
2
2
|
|
|
3
|
-
Status:
|
|
3
|
+
Status: `0.4.0-alpha.1` alpha of the extension contract and agent tooling on
|
|
4
|
+
top of the `0.3.0` self-hosted release. Production approval remains specific to
|
|
4
5
|
the workload and deployment environment.
|
|
5
6
|
This register describes the current public runtime, not future promises.
|
|
6
7
|
Use the contract and docs from the same pinned commit as your installed runtime.
|
|
7
8
|
|
|
8
9
|
## What is aligned
|
|
9
10
|
|
|
10
|
-
- One portable YAML project, explicit includes,
|
|
11
|
+
- One portable YAML project, explicit includes, one handler per route (redirect, respond, page, static, download, function, link, proxy, conditional or extension),
|
|
11
12
|
per-route middleware and consistent request/response validation.
|
|
12
13
|
- One starter with a function route first and an ordinary redirect second.
|
|
13
14
|
Clone urlcode-template or use `urlcode init`; neither requires a database.
|
|
@@ -72,12 +73,13 @@ License selection is resolved: URLCode is released under the Apache License 2.0,
|
|
|
72
73
|
`package.json` declares it, and the repository carries the full license text.
|
|
73
74
|
The remaining gates above are engineering and operational, not legal.
|
|
74
75
|
|
|
75
|
-
The
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
execution target
|
|
80
|
-
capabilities
|
|
76
|
+
The unreleased next-phase source now includes strict bulk/provider interchange,
|
|
77
|
+
local recipes, TypeScript authoring, bounded self-hosted proxy/signals and read-only
|
|
78
|
+
MCP. Local AWS/Vercel/Cloudflare adapter tests and deployment probe tooling exist,
|
|
79
|
+
but actual provider deployments remain unverified. Node process/container hosting
|
|
80
|
+
remains the reference execution target. Guest networking, durable signals and
|
|
81
|
+
realtime capabilities are not provided. See [implementation status](NEXT-PHASE-PLAN.md)
|
|
82
|
+
and [roadmap](../ROADMAP.md); these additions do not close the operational gates above.
|
|
81
83
|
|
|
82
84
|
The [internal security audit](SECURITY-AUDIT.md) records reproduced findings, fixes
|
|
83
85
|
and prioritized gaps. Its regressions supplement these gates; they do not replace
|
|
@@ -91,5 +93,5 @@ credentials, atomic SQLite mutation audits, executable local/CI operational dril
|
|
|
91
93
|
and a main-only candidate signing/SBOM workflow.
|
|
92
94
|
|
|
93
95
|
Still required: [independent review](SANDBOX-REVIEW.md), [actual deployment proof](OPERATIONAL-PROOF.md),
|
|
94
|
-
and publication/support arrangements. The Apache-2.0 license and the 0.
|
|
96
|
+
and publication/support arrangements. The Apache-2.0 license and the 0.3.0 self-hosted
|
|
95
97
|
release do not close the security and deployment gates. See [release process](RELEASE-SECURITY.md).
|
package/docs/RELEASE-SECURITY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Candidate and release security process
|
|
2
2
|
|
|
3
|
-
URLCode 0.
|
|
3
|
+
URLCode 0.3.0 is the Apache-2.0 self-hosted baseline; licensing is defined
|
|
4
4
|
in [LICENSE](../LICENSE). Two workflows share one audited build path and differ
|
|
5
5
|
only in what they do with its output:
|
|
6
6
|
|
|
@@ -14,6 +14,16 @@ only in what they do with its output:
|
|
|
14
14
|
Neither workflow is a statement that a release is production-ready; see
|
|
15
15
|
[release readiness](RELEASE-READINESS.md).
|
|
16
16
|
|
|
17
|
+
## Publishing an alpha
|
|
18
|
+
|
|
19
|
+
An alpha such as `0.4.0-alpha.1` follows the same path: tag `v0.4.0-alpha.1`
|
|
20
|
+
on a commit that is already on main. The release workflow publishes to npm
|
|
21
|
+
only when the repository variable `PUBLISH_NPM` is `true` and the npm trusted
|
|
22
|
+
publisher for this repository and `release.yml` exists; otherwise the run is
|
|
23
|
+
artifacts-only (a GitHub release with the signed tarball). Publish order is
|
|
24
|
+
core → ui → auth → admin, because the extension packages declare
|
|
25
|
+
`@jimhoyd/urlcode >=0.4.0-alpha.1 <0.5.0` and must resolve the core alpha.
|
|
26
|
+
|
|
17
27
|
1. Report vulnerabilities privately through [GitHub advisories](https://github.com/jimhoyd-com/urlcode/security/advisories/new).
|
|
18
28
|
The maintainer triages impact, confirms affected exact revisions, coordinates a
|
|
19
29
|
fix/retest privately, and publishes an advisory with upgrade guidance when safe.
|
|
@@ -47,10 +57,23 @@ Neither workflow is a statement that a release is production-ready; see
|
|
|
47
57
|
signing key is stored. Signing permissions exist only in this manual job; build
|
|
48
58
|
commands run in a container without passing GitHub tokens. Candidate files are
|
|
49
59
|
retained as GitHub Actions artifacts for 30 days. A release additionally attaches
|
|
50
|
-
them to the GitHub release, and publishes to npm
|
|
51
|
-
|
|
60
|
+
them to the GitHub release, and publishes to npm and to GHCR when those
|
|
61
|
+
repository variables are enabled.
|
|
62
|
+
|
|
63
|
+
**npm publication holds no credential.** The registry is configured with a
|
|
64
|
+
trusted publisher naming this repository and `release.yml`, so the publish
|
|
65
|
+
step exchanges the job's OIDC identity for a credential that lives for the
|
|
66
|
+
length of one publish. There is no npm token in the repository's secrets to
|
|
67
|
+
leak, revoke or rotate, and a fork or another workflow cannot publish under
|
|
68
|
+
this package's name. Provenance is generated on that same identity, so
|
|
69
|
+
`--provenance` is not passed and its absence is not a downgrade.
|
|
70
|
+
|
|
71
|
+
A bearer token would silently take precedence over this exchange, so the
|
|
72
|
+
publish step must reference none; `test/release.test.ts` fails if one
|
|
73
|
+
reappears in it, and checks the npm and Node floors below which the exchange
|
|
74
|
+
is not attempted at all.
|
|
52
75
|
5. Download the candidate for the intended commit and verify **each file**, e.g.
|
|
53
|
-
`gh attestation verify urlcode-0.
|
|
76
|
+
`gh attestation verify jimhoyd-urlcode-0.3.0.tgz --repo jimhoyd-com/urlcode --signer-workflow jimhoyd-com/urlcode/.github/workflows/candidate.yml --source-ref refs/heads/main --source-digest APPROVED_COMMIT_SHA`
|
|
54
77
|
(use `release.yml` as the signer workflow for a tagged release).
|
|
55
78
|
Check the verified provenance's source commit against the approved commit, and
|
|
56
79
|
compare package/SBOM hashes with the signed manifest. A signature establishes
|
package/docs/SECURITY-AUDIT.md
CHANGED
|
@@ -100,7 +100,7 @@ repository-governance follow-up pins them and enables dependency maintenance,
|
|
|
100
100
|
secret protection, CodeQL and private reporting; see [governance](../GOVERNANCE.md).
|
|
101
101
|
CI now also gates runtime advisories with `npm audit --omit=dev`. A manual main-only
|
|
102
102
|
signed candidate/SBOM workflow is now defined; see
|
|
103
|
-
[release security](RELEASE-SECURITY.md).
|
|
103
|
+
[release security](RELEASE-SECURITY.md). A tagged release publishes to npm with provenance. The 0.1.0 release is licensed under
|
|
104
104
|
Apache-2.0; the license does not close the independent-review gates.
|
|
105
105
|
|
|
106
106
|
**Application responsibility:** HTML/JS assets are active browser content; choose
|
package/docs/SPECIFICATION.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
# Implemented
|
|
1
|
+
# Implemented project contract
|
|
2
2
|
|
|
3
3
|
This document and [JSON Schema](../schemas/urlcode.schema.json) describe
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
the source contract, including unreleased additions after 0.3.0.
|
|
5
|
+
`version: "1"` remains the project-format contract. Unsupported fields
|
|
6
|
+
are rejected rather than interpreted as future behavior.
|
|
6
7
|
|
|
7
8
|
## Files and validation
|
|
8
9
|
|
|
@@ -29,12 +30,12 @@ deadline; individual synchronous operations are not preempted. At most 1,000 par
|
|
|
29
30
|
Keys are absolute case-sensitive paths. Trailing slashes are significant.
|
|
30
31
|
Parameters occupy whole segments, e.g. `/p/{id}`, with distinct identifier names.
|
|
31
32
|
Each parameter matches exactly one nonempty segment, never across `/`; it is not
|
|
32
|
-
greedy. No regex paths, host
|
|
33
|
+
greedy. No regex paths, client-controlled host dispatch or dot segments. Only static directory mounts
|
|
33
34
|
support a terminal `/*` wildcard with an otherwise literal path. Route keys cannot contain
|
|
34
35
|
percent encoding, spaces, backslashes or query strings. Path length is limited
|
|
35
36
|
to 2,048 characters and 32 segments. `/_urlcode` is reserved.
|
|
36
37
|
|
|
37
|
-
One handler per route: `function`, `redirect`, `page`, `static`, `download`, `respond` or `
|
|
38
|
+
One handler per route: `function`, `redirect`, `page`, `static`, `download`, `respond`, `link`, `conditional` or `proxy`.
|
|
38
39
|
See [asset configuration](ASSETS.md) for file handlers. Optional properties:
|
|
39
40
|
|
|
40
41
|
- `methods`: unique HTTP methods; default GET and HEAD. Explicit lists are exact;
|
|
@@ -67,6 +68,37 @@ path wins and the generated one is logged as shadowed. Absolute URLs come from
|
|
|
67
68
|
the operator's `--origin`; `sitemap` refuses activation without one. See
|
|
68
69
|
[site conventions](SITE.md).
|
|
69
70
|
|
|
71
|
+
## Exact conditions and duplicate-path alternatives
|
|
72
|
+
|
|
73
|
+
Optional route `match` conjunctively compares exact query/header/cookie strings,
|
|
74
|
+
an uppercase method and the canonical authority of the operator-configured
|
|
75
|
+
public origin. Host/forwarded headers never select the trusted host. A guard
|
|
76
|
+
mismatch returns 404 without trying a less-specific path; route method admission
|
|
77
|
+
still applies after the guard. Conditions are not authentication or authorization.
|
|
78
|
+
|
|
79
|
+
The `conditional` handler puts alternatives under one existing route key:
|
|
80
|
+
`cases` contains 1–16 `{match, redirect}` or `{match, respond}` entries; optional
|
|
81
|
+
`fallback` contains exactly one redirect/respond handler. Duplicate YAML paths
|
|
82
|
+
remain invalid. Cases must be provably disjoint: each pair needs a shared
|
|
83
|
+
predicate with different required values. Cases run before fallback; no matching
|
|
84
|
+
case and no fallback returns 404. Nested cases and branch-local bindings,
|
|
85
|
+
middleware or policy are unsupported. Shared inputs, methods, headers,
|
|
86
|
+
middleware and policies stay at route level.
|
|
87
|
+
|
|
88
|
+
Each query/header/cookie map has 1–16 comparisons; names have at most 128
|
|
89
|
+
characters and values 1,024. Query comparisons use decoded raw strings without
|
|
90
|
+
parameter defaults/coercion. Cookies use unquoted wire values and an 8 KiB input
|
|
91
|
+
limit. Missing and empty are different. Duplicate examined scalar inputs return
|
|
92
|
+
400 when the transport exposes their counts. Header names normalize to lowercase;
|
|
93
|
+
authentication and transport headers cannot be predicates. No regex, geo/device
|
|
94
|
+
inference, wildcard or arbitrary-code conditions are supported.
|
|
95
|
+
|
|
96
|
+
Conditional routing requires cache disabled or no-store and forces downstream
|
|
97
|
+
no-store responses. Explicit fixtures are required for branch coverage.
|
|
98
|
+
Self-hosted, AWS and Vercel use the shared matcher; Cloudflare refuses conditions
|
|
99
|
+
until its artifact compiler supports them. See [conditions](CONDITIONS.md) and
|
|
100
|
+
the [executable example](../examples/conditions).
|
|
101
|
+
|
|
70
102
|
## HTTP request/response configuration
|
|
71
103
|
|
|
72
104
|
Routes accept `request.body` validation and `response.headers` overrides. The
|
|
@@ -161,8 +193,25 @@ export default function hello(request, { args, env }) {
|
|
|
161
193
|
}
|
|
162
194
|
```
|
|
163
195
|
|
|
196
|
+
`function` also accepts a string: `function: functions/hello.mjs`. Document
|
|
197
|
+
validation normalizes it to the long form above before routing, auditing,
|
|
198
|
+
explaining or hashing the project: `source` is the string, `args` maps every
|
|
199
|
+
`{param}` segment of the path to `{from: path, name: param}`, and each such
|
|
200
|
+
parameter the route does not already declare under `parameters` (by name, with
|
|
201
|
+
`in: path`) is appended as `{in: path, required: true, schema: {type: string,
|
|
202
|
+
minLength: 1, maxLength: 128}}`. Declared parameters keep their own schema and
|
|
203
|
+
order. The string must be a project-relative `.mjs` or `.js` path without `..`
|
|
204
|
+
segments; anything else is refused with the route path named. A `middleware`
|
|
205
|
+
entry may likewise be a string, normalized to `{source: <string>}`. Only the
|
|
206
|
+
long form exists after loading, so `routes`, `audit`, `explain`, revision hashes
|
|
207
|
+
and the field reference describe the expansion.
|
|
208
|
+
|
|
164
209
|
ES modules only (`.mjs` or `.js`, independent of Node package settings).
|
|
165
|
-
TypeScript
|
|
210
|
+
[Build-time TypeScript authoring](TYPESCRIPT-AUTHORING.md) can produce these
|
|
211
|
+
JavaScript modules in a separate output project; serving does not transpile them.
|
|
212
|
+
The build never imports application code into Node, uses fixed compiler settings,
|
|
213
|
+
and does not perform semantic type checking. Grants must target the built
|
|
214
|
+
configuration/source revision. `export` defaults to `default`. Functions execute
|
|
166
215
|
inside QuickJS/WASM, never through Node imports. Only relative `.js`/`.mjs`
|
|
167
216
|
project imports are supported, with a snapshotted dependency graph. No bare/npm,
|
|
168
217
|
Node built-in, remote, dynamic source imports or `import.meta`. Runtime-created
|
|
@@ -206,8 +255,9 @@ not arbitrary Host/forwarded headers. Request/response bodies default to 1 MiB;
|
|
|
206
255
|
response headers 16 KiB, maximum 256 pairs. Hop-by-hop headers are stripped;
|
|
207
256
|
cookies are preserved individually. Default response cache policy is `no-store`.
|
|
208
257
|
|
|
209
|
-
No unrestricted host execution option exists.
|
|
210
|
-
|
|
258
|
+
No unrestricted host execution option exists. Declarative proxy and webhook
|
|
259
|
+
signals use the separately granted host broker described in [egress](EGRESS.md);
|
|
260
|
+
guests still have no fetch API or general persistent state capability. Approved secrets can be
|
|
211
261
|
returned by code that receives them; isolation does not automatically enforce
|
|
212
262
|
information-flow rules on authorized inputs. Keep grants narrow and review the
|
|
213
263
|
exact pinned revision. The sandbox still needs independent security review before hostile multi-tenant use.
|
|
@@ -230,3 +280,40 @@ The health `version` combines route-definition and asset-representation digests,
|
|
|
230
280
|
not a full artifact digest
|
|
231
281
|
or secret fingerprint. Production release identity should be the Git commit and
|
|
232
282
|
container image digest. See [operations](OPERATIONS.md).
|
|
283
|
+
|
|
284
|
+
See [capabilities and normalized route representation](CAPABILITIES.md) for the target catalog,
|
|
285
|
+
programmatic compatibility analysis and provider verification limits.
|
|
286
|
+
|
|
287
|
+
## Authoring, conversion and verification tools
|
|
288
|
+
|
|
289
|
+
[Interchange](INTERCHANGE.md) imports and exports a strict literal redirect
|
|
290
|
+
subset with source diagnostics and dry-run reports. Provider conversions refuse
|
|
291
|
+
semantic differences by default; explicit acknowledgment retains warnings and
|
|
292
|
+
never reports lossless behavior. [Bulk import](BULK.md) shards CSV/JSON/YAML rows
|
|
293
|
+
into ordinary includes while retaining runtime resource limits. [Recipes](RECIPES.md)
|
|
294
|
+
are local Git-owned examples; they grant no capabilities. [Build-time TypeScript](TYPESCRIPT-AUTHORING.md)
|
|
295
|
+
is separate from runtime execution.
|
|
296
|
+
|
|
297
|
+
The [tooling SDK and optional local MCP](TOOLING.md) inspect and validate without
|
|
298
|
+
executing handlers or reading binding values. [Provider conformance](PROVIDER-VERIFICATION.md)
|
|
299
|
+
distinguishes local adapter replay from actual deployment observations; no real
|
|
300
|
+
provider deployment is implied by CI. [Proxy and signal egress](EGRESS.md) requires
|
|
301
|
+
external revision-pinned operator grants and bounded host-owned transport;
|
|
302
|
+
project declarations cannot grant network authority to themselves or guests.
|
|
303
|
+
|
|
304
|
+
## Bounded outbound behavior
|
|
305
|
+
|
|
306
|
+
The proxy handler and webhook signals require external revision-pinned origin
|
|
307
|
+
grants. [Egress](EGRESS.md) specifies request and response semantics, DNS pinning,
|
|
308
|
+
header filtering, size/time/concurrency limits, secret binding, signal guarantees
|
|
309
|
+
and shutdown. Project declarations cannot grant network authority to themselves.
|
|
310
|
+
All non-self-hosted targets refuse these capabilities.
|
|
311
|
+
|
|
312
|
+
## Operator-installed extension handlers
|
|
313
|
+
|
|
314
|
+
The optional `extensions` map declares version-1 extension configuration.
|
|
315
|
+
`extension: name` handlers require exclusive literal `/prefix/*` mounts and
|
|
316
|
+
explicit operator registration pinned to the project revision. Optional
|
|
317
|
+
`policies.extensions` requirements are validated by the named extension and
|
|
318
|
+
authorized before cache access. See [extension contracts](EXTENSIONS.md) for
|
|
319
|
+
configuration, trust boundaries, lifecycle and target restrictions.
|