@jimhoyd/urlcode 0.4.0-alpha.1 → 0.4.0-alpha.2
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 +24 -8
- package/.claude/skills/urlcode-operations/SKILL.md +10 -16
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +75 -62
- package/ROADMAP.md +61 -16
- package/SECURITY.md +23 -8
- package/dist/BUILD-MANIFEST.json +38 -43
- package/dist/agents-guide.js +18 -18
- package/dist/build-static.js +134 -0
- package/dist/capabilities.js +85 -31
- package/dist/capability-query.js +0 -1
- package/dist/cli.js +23 -31
- package/dist/compliance-rules/baseline.js +2 -10
- package/dist/compliance-rules/privacy.js +5 -16
- package/dist/compliance-rules/shared.js +0 -2
- package/dist/compliance.js +6 -8
- package/dist/config.js +15 -8
- package/dist/context.js +9 -10
- package/dist/examples.js +2 -2
- package/dist/explain-cli.js +3 -3
- package/dist/explain.js +5 -6
- package/dist/extensions.js +61 -2
- package/dist/function-sources.js +34 -2
- package/dist/function-worker.js +3 -1
- package/dist/functions.js +84 -13
- package/dist/guest-api.js +29 -3
- package/dist/index.js +3 -6
- package/dist/manifest.js +5 -7
- package/dist/mcp.js +1 -1
- package/dist/observability.js +1 -21
- package/dist/policies/cache.js +8 -3
- package/dist/policy.js +28 -9
- package/dist/project-tests.js +3 -3
- package/dist/readiness.js +32 -9
- package/dist/router.js +5 -7
- package/dist/runtime.js +77 -58
- package/dist/sandbox.js +48 -0
- package/dist/scaffold.js +0 -0
- package/dist/scripts/operational-drills.js +12 -54
- package/dist/server.js +3 -29
- package/dist/tooling.js +1 -1
- package/dist/trusted-functions.js +210 -0
- package/dist/types/build-static.d.ts +43 -0
- package/dist/types/capabilities.d.ts +14 -5
- package/dist/types/compliance-rules/shared.d.ts +0 -2
- package/dist/types/compliance.d.ts +0 -3
- package/dist/types/config.d.ts +2 -1
- package/dist/types/context.d.ts +2 -1
- package/dist/types/examples.d.ts +1 -1
- package/dist/types/extensions.d.ts +55 -0
- package/dist/types/function-sources.d.ts +4 -0
- package/dist/types/functions.d.ts +48 -5
- package/dist/types/guest-api.d.ts +1 -0
- package/dist/types/index.d.ts +3 -6
- package/dist/types/manifest.d.ts +1 -3
- package/dist/types/observability.d.ts +1 -14
- package/dist/types/project-tests.d.ts +1 -2
- package/dist/types/readiness.d.ts +10 -3
- package/dist/types/router.d.ts +2 -1
- package/dist/types/runtime.d.ts +0 -27
- package/dist/types/sandbox.d.ts +12 -0
- package/dist/types/scaffold.d.ts +0 -2
- package/dist/types/server.d.ts +1 -4
- package/dist/types/tooling.d.ts +3 -3
- package/dist/types/trusted-functions.d.ts +29 -0
- package/dist/types/types.d.ts +14 -7
- package/dist/types/verify-deployment.d.ts +2 -2
- package/dist/types.js +17 -4
- package/dist/typescript-authoring.js +55 -17
- package/dist/verify-deployment.js +3 -3
- package/docs/AI-AUTHORING.md +104 -9
- package/docs/AWS.md +4 -4
- package/docs/BEST-PRACTICES.md +3 -2
- package/docs/CAPABILITIES.md +29 -16
- package/docs/CAPACITY.md +128 -31
- package/docs/CLOUDFLARE.md +1 -2
- package/docs/COMPLIANCE.md +6 -9
- package/docs/DEPLOYMENT-CHECKS.md +1 -1
- package/docs/EXTENSIONS.md +183 -11
- package/docs/FRAMEWORK.md +35 -19
- package/docs/FUNCTION-SECURITY.md +129 -32
- package/docs/INSTALL.md +0 -5
- package/docs/LOAD-TESTING.md +4 -4
- package/docs/MIDDLEWARE.md +27 -16
- package/docs/MONITORING.md +2 -19
- package/docs/NEXT-PHASE-PLAN.md +12 -4
- package/docs/NEXT-STEPS.md +259 -40
- package/docs/OBSERVABILITY.md +7 -16
- package/docs/OPEN-DECISIONS.md +212 -0
- package/docs/OPERATIONAL-PROOF.md +26 -30
- package/docs/OPERATIONS.md +23 -32
- package/docs/POLICIES.md +15 -4
- package/docs/PRERENDER.md +2 -2
- package/docs/PROJECT-DIRECTION.md +34 -9
- package/docs/README.md +13 -11
- package/docs/RELEASE-READINESS.md +49 -29
- package/docs/RELEASE-SECURITY.md +89 -3
- package/docs/RESILIENCE.md +16 -15
- package/docs/ROUTING.md +8 -10
- package/docs/SANDBOX-REVIEW.md +19 -6
- package/docs/SCAFFOLDING.md +0 -2
- package/docs/SECURITY-AUDIT.md +40 -0
- package/docs/SPECIFICATION.md +60 -26
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
- package/docs/SPIKE-BUSINESS-SUITE.md +8 -0
- package/docs/SPIKE-CORE-LAYERING.md +337 -0
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +2 -2
- package/docs/SPIKE-EXTENSIONS.md +5 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +4 -2
- package/docs/SPIKE-MONOREPO.md +322 -0
- package/docs/STARTERS.md +1 -1
- package/docs/STATIC.md +94 -0
- package/docs/TOOLING.md +13 -9
- package/docs/TUNNELS.md +0 -3
- package/docs/TYPESCRIPT-AUTHORING.md +27 -12
- package/docs/TYPESCRIPT.md +25 -4
- package/docs/USABILITY-REVIEW.md +7 -1
- package/docs/VERCEL.md +4 -5
- package/docs/VERSION-ALIGNMENT.md +205 -0
- package/docs/YAML-GUIDE.md +0 -3
- package/docs/YAML-REFERENCE.md +16 -6
- package/docs/policies/cache.md +13 -0
- package/examples/assets/example.yaml +1 -1
- package/examples/aws/example.yaml +1 -1
- package/examples/cloudflare/example.yaml +1 -1
- package/examples/conditions/example.yaml +1 -1
- package/examples/cookbook/example.yaml +1 -1
- package/examples/cookbook/middleware/bucket.mjs +12 -2
- package/examples/cookbook/middleware/locale.mjs +7 -3
- package/examples/egress/example.yaml +1 -1
- package/examples/extensions/example.yaml +1 -1
- package/examples/prerender/README.md +2 -2
- package/examples/prerender/example.yaml +1 -1
- package/examples/provider-conformance/example.yaml +1 -1
- package/examples/vercel/example.yaml +1 -1
- package/llms-full.txt +594 -219
- package/llms.txt +23 -12
- package/package.json +10 -3
- package/packaging/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +24 -8
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +10 -16
- package/recipes/authenticated-json-api/recipe.yaml +1 -1
- package/recipes/contact-form/recipe.yaml +1 -1
- package/recipes/cors-api/recipe.yaml +1 -1
- package/recipes/health-page/recipe.yaml +1 -1
- package/recipes/json-api/recipe.yaml +1 -1
- package/recipes/middleware/middleware/bucket.mjs +12 -2
- package/recipes/middleware/middleware/locale.mjs +7 -3
- package/recipes/middleware/recipe.yaml +1 -1
- package/recipes/protected-download/recipe.yaml +1 -1
- package/recipes/redirect/recipe.yaml +1 -1
- package/recipes/static-plus-api/recipe.yaml +1 -1
- package/recipes/typescript/README.md +2 -1
- package/recipes/typescript/recipe.yaml +1 -1
- package/recipes/webhook-receiver/README.md +5 -1
- package/recipes/webhook-receiver/recipe.yaml +2 -1
- package/recipes/webhook-receiver/urlcode.yaml +7 -0
- package/schemas/recipe.schema.json +4 -3
- package/schemas/urlcode.schema.json +14 -41
- package/skills/urlcode/SKILL.md +29 -8
- package/starters/default/AGENTS.md +18 -18
- package/starters/default/urlcode.yaml +0 -1
- package/dist/link-api.js +0 -136
- package/dist/link-cli.js +0 -141
- package/dist/link-events.js +0 -76
- package/dist/link-records.js +0 -31
- package/dist/link-store-worker.js +0 -150
- package/dist/link-store.js +0 -250
- package/dist/management-policy.js +0 -40
- package/dist/sqlite-version.js +0 -6
- package/dist/types/link-api.d.ts +0 -30
- package/dist/types/link-cli.d.ts +0 -37
- package/dist/types/link-events.d.ts +0 -27
- package/dist/types/link-records.d.ts +0 -11
- package/dist/types/link-store-worker.d.ts +0 -1
- package/dist/types/link-store.d.ts +0 -130
- package/dist/types/management-policy.d.ts +0 -8
- package/dist/types/sqlite-version.d.ts +0 -1
- package/docs/DYNAMIC-LINKS.md +0 -61
- package/docs/MANAGEMENT-SECURITY.md +0 -82
- package/docs/links/cli.md +0 -110
- package/docs/links/limits.md +0 -175
- package/docs/links/management-api.md +0 -80
- package/docs/links/pools.md +0 -75
- package/docs/links/setup.md +0 -135
- package/docs/yaml/links.md +0 -30
- package/examples/live-links/README.md +0 -11
- package/examples/live-links/example.yaml +0 -21
- package/examples/live-links/tests/requests.json +0 -6
- package/examples/live-links/urlcode.yaml +0 -16
package/llms.txt
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
# URLCode
|
|
2
2
|
|
|
3
3
|
> A portable runtime for programmable URL behavior, and the framework that grows
|
|
4
|
-
> from it: routes in YAML,
|
|
5
|
-
>
|
|
6
|
-
> `version: "1"`. Core is Apache-2.0; `0.4.0-alpha.
|
|
4
|
+
> from it: routes in YAML, functions and middleware, then accounts, administration and
|
|
5
|
+
> stored links as operator-installed extensions. Stable project format
|
|
6
|
+
> `version: "1"`. Core is Apache-2.0; this revision is `0.4.0-alpha.2`, which makes
|
|
7
|
+
> `function`/`middleware` routes trusted by default with `sandbox: true` as the
|
|
8
|
+
> per-route opt-in; `0.4.0-alpha.1` is the newest alpha published to npm, on top of
|
|
7
9
|
> the `0.3.0` release. The auth, admin and ui extension packages are on npm as
|
|
8
|
-
> `0.1.0-alpha.
|
|
10
|
+
> `0.1.0-alpha.x`, source-complete, review pending.
|
|
9
11
|
|
|
10
12
|
Use the schema and docs from the runtime revision you run. Do not assume Node
|
|
11
|
-
or fetch
|
|
12
|
-
interpolation, or packages named in YAML. Secrets need external revision-pinned
|
|
13
|
+
or fetch inside a `sandbox: true` function, regex routes, database access,
|
|
14
|
+
global middleware, YAML interpolation, or packages named in YAML. Secrets need external revision-pinned
|
|
13
15
|
grants. Unsupported features fail with the route named; nothing degrades silently.
|
|
14
16
|
|
|
15
17
|
Agents that explicitly want the complete consolidated reference in one fetch should read
|
|
16
18
|
[llms-full.txt](llms-full.txt), generated from the documents below (about 50k tokens, estimated).
|
|
17
19
|
|
|
20
|
+
## Declarative-first default
|
|
21
|
+
|
|
22
|
+
> Use URLCode's highest-level declarative features whenever possible. Generate custom code only when the framework cannot express the requirement.
|
|
23
|
+
|
|
24
|
+
Check the installed version's primitives, YAML configuration, policies, supported
|
|
25
|
+
extensions and recipes/templates before writing a custom function or middleware.
|
|
26
|
+
Keep necessary custom code focused and report the capability gap; never invent
|
|
27
|
+
fields or bypass target limits or operator grants. See [the design principle](docs/PROJECT-DIRECTION.md#design-principle-declarative-first).
|
|
28
|
+
|
|
18
29
|
## Authoring
|
|
19
30
|
- [AI authoring contract](docs/AI-AUTHORING.md): workflow, capability matrix, checks.
|
|
20
31
|
- [Authoring skill](.claude/skills/urlcode-authoring/SKILL.md): loadable authoring skill shipped with this revision; see [distribution](docs/AI-AUTHORING.md#agent-skills).
|
|
@@ -24,12 +35,11 @@ Agents that explicitly want the complete consolidated reference in one fetch sho
|
|
|
24
35
|
- [Field reference](docs/YAML-REFERENCE.md): generated exhaustive field inventory.
|
|
25
36
|
- [Semantics](docs/SPECIFICATION.md): validation, defaults and sandbox API.
|
|
26
37
|
- [Runnable cookbook](examples/cookbook/README.md): 25 routes with HTTP fixtures.
|
|
27
|
-
- [Dynamic links](docs/DYNAMIC-LINKS.md): optional SQLite, live mutations, management API and limits.
|
|
28
38
|
- [Route matching](docs/ROUTING.md): precedence, non-greedy parameters, updates.
|
|
29
39
|
- [Middleware](docs/MIDDLEWARE.md): next(), state, ordering and native body limits.
|
|
30
40
|
- [Policies](docs/POLICIES.md): optional host-enforced `policies`/`profiles` keys, all off by default: `throttle`, `agents`, `security`, `compression`, `cache`; merge rules and per-target support.
|
|
31
41
|
- [Plugins](docs/PLUGINS.md): host hook API operators pass in code; never named in YAML.
|
|
32
|
-
- [TypeScript](docs/TYPESCRIPT.md): the package ships declarations for every export (`urlcode`, `@jimhoyd/urlcode/plugins`, `@jimhoyd/urlcode/policies`, `@jimhoyd/urlcode/observability`, `@jimhoyd/urlcode/compliance`, `@jimhoyd/urlcode/prerender`, `@jimhoyd/urlcode/aws`, `@jimhoyd/urlcode/vercel`, `@jimhoyd/urlcode/cloudflare`); the runtime source is TypeScript, `dist/` is its stripped JavaScript.
|
|
42
|
+
- [TypeScript](docs/TYPESCRIPT.md): the package ships declarations for every export (`urlcode`, `@jimhoyd/urlcode/plugins`, `@jimhoyd/urlcode/policies`, `@jimhoyd/urlcode/observability`, `@jimhoyd/urlcode/compliance`, `@jimhoyd/urlcode/prerender`, `@jimhoyd/urlcode/sandbox`, `@jimhoyd/urlcode/aws`, `@jimhoyd/urlcode/vercel`, `@jimhoyd/urlcode/cloudflare`); the runtime source is TypeScript, `dist/` is its stripped JavaScript.
|
|
33
43
|
- [HTTP](docs/HTTP.md): methods, request bodies and response headers.
|
|
34
44
|
- [Assets](docs/ASSETS.md): pages, MIME, downloads, cache and ranges.
|
|
35
45
|
- [Site conventions](docs/SITE.md): optional top-level `site` key, all off by default: `robots`, `sitemap`, `favicon`, `securityTxt`, `llms` generate native routes; declared routes win; absolute URLs need `--origin`.
|
|
@@ -46,10 +56,9 @@ Agents that explicitly want the complete consolidated reference in one fetch sho
|
|
|
46
56
|
## Routes and handlers
|
|
47
57
|
- [Routing](docs/ROUTING.md): exact and `{param}` paths, precedence, `/*` only on static and extension mounts.
|
|
48
58
|
- [HTTP](docs/HTTP.md): methods, validated inputs, bodies, response headers, cookies.
|
|
49
|
-
- [Function security](docs/FUNCTION-SECURITY.md): QuickJS/WASM
|
|
59
|
+
- [Function security](docs/FUNCTION-SECURITY.md): trusted and unsandboxed by default, `sandbox: true` QuickJS/WASM opt-in, Request/Response subset, operator grants.
|
|
50
60
|
- [Middleware](docs/MIDDLEWARE.md) and [examples](docs/MIDDLEWARE-EXAMPLES.md): `next()`, state, ordering; also `urlcode recipes add middleware`.
|
|
51
61
|
- [Assets](docs/ASSETS.md): pages, static, downloads, MIME, ranges. [Prerender](docs/PRERENDER.md): render once, no request-time code.
|
|
52
|
-
- [Dynamic links](docs/DYNAMIC-LINKS.md): `link` handler, SQLite store, CLI, private management API.
|
|
53
62
|
- [Conditions](docs/CONDITIONS.md): exact predicates, disjoint redirect/respond cases, no-store.
|
|
54
63
|
- [Egress](docs/EGRESS.md): bounded HTTPS proxy and best-effort signals behind operator grants; self-hosted only.
|
|
55
64
|
- [Policies](docs/POLICIES.md): `throttle`, `agents`, `security`, `compression`, `cache`; all off unless declared. [Site](docs/SITE.md): robots, sitemap, favicon, security.txt, llms.txt.
|
|
@@ -57,19 +66,21 @@ Agents that explicitly want the complete consolidated reference in one fetch sho
|
|
|
57
66
|
- [Interchange](docs/INTERCHANGE.md), [bulk import](docs/BULK.md), [recipes](docs/RECIPES.md) (`urlcode recipes search`, `examples search`), [TypeScript guests](docs/TYPESCRIPT-AUTHORING.md).
|
|
58
67
|
|
|
59
68
|
## Extensions (accounts, administration, presentation)
|
|
60
|
-
- [Extensions](docs/EXTENSIONS.md): `extensions.<name>` blocks, `extension` mounts, `policies.extensions`, the operator host file, `@jimhoyd/urlcode/extensions`.
|
|
69
|
+
- [Extensions](docs/EXTENSIONS.md): `extensions.<name>` blocks, `extension` mounts, `policies.extensions`, the operator host file, `@jimhoyd/urlcode/extensions`. Project-level lifecycle hooks run trusted via plain `import()`, or sandboxed via `@jimhoyd/urlcode/sandbox`'s `SandboxPool`.
|
|
61
70
|
- [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth): npm: @jimhoyd/urlcode-auth; accounts, sessions, MFA, roles, account page; its own llms.txt.
|
|
62
71
|
- [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin): npm: @jimhoyd/urlcode-admin; users, sessions, roles, audit, cases; its own llms.txt.
|
|
63
72
|
- [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui): npm: @jimhoyd/urlcode-ui; escaped templates, shadcn/ui partials, themes, translations; its own llms.txt.
|
|
73
|
+
- urlcode-dynamic-link (planned, not yet published): stored short links move here as a mount-based extension; core no longer has a native `link` handler.
|
|
64
74
|
- [Plugins](docs/PLUGINS.md): host hook API in operator code, never named in YAML.
|
|
65
75
|
|
|
66
76
|
## Tooling and API
|
|
67
77
|
- [Tooling SDK and MCP](docs/TOOLING.md): `urlcode mcp`, read-only inspection, validation, conversion previews.
|
|
68
|
-
- [TypeScript](docs/TYPESCRIPT.md): declarations for `@jimhoyd/urlcode` and its `/plugins`, `/policies`, `/observability`, `/compliance`, `/prerender`, `/extensions`, `/aws`, `/vercel`, `/cloudflare` entries.
|
|
78
|
+
- [TypeScript](docs/TYPESCRIPT.md): declarations for `@jimhoyd/urlcode` and its `/plugins`, `/policies`, `/observability`, `/compliance`, `/prerender`, `/extensions`, `/sandbox`, `/aws`, `/vercel`, `/cloudflare` entries.
|
|
69
79
|
- [Capabilities](docs/CAPABILITIES.md): per-target support; `urlcode capabilities --target NAME`.
|
|
70
80
|
|
|
71
81
|
## Operations
|
|
72
82
|
- [Operations](docs/OPERATIONS.md), [install](docs/INSTALL.md), [deployment checks](docs/DEPLOYMENT-CHECKS.md), [CI action](docs/CI.md).
|
|
73
83
|
- [Readiness](docs/READINESS.md), [capacity](docs/CAPACITY.md), [performance](docs/PERFORMANCE.md), [resilience](docs/RESILIENCE.md), [observability](docs/OBSERVABILITY.md).
|
|
74
84
|
- [Vercel](docs/VERCEL.md), [AWS](docs/AWS.md), [Cloudflare](docs/CLOUDFLARE.md): adapters with local conformance tests; no provider deployment verified yet.
|
|
85
|
+
- [Static hosting](docs/STATIC.md): `urlcode build --target static` compiles redirects/pages/static/downloads to S3 + CloudFront objects and redirect metadata; no server, so function/middleware/extension/proxy/signals/conditions/parameters/bindings/policies are all refused; GitHub Pages is explicitly out of scope.
|
|
75
86
|
- [Release readiness](docs/RELEASE-READINESS.md), [roadmap](ROADMAP.md): what is proven, what is planned.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jimhoyd/urlcode",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.2",
|
|
4
4
|
"description": "Portable runtime for programmable URL behavior",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -69,6 +69,11 @@
|
|
|
69
69
|
"development": "./src/extensions.ts",
|
|
70
70
|
"default": "./dist/extensions.js"
|
|
71
71
|
},
|
|
72
|
+
"./sandbox": {
|
|
73
|
+
"types": "./dist/types/sandbox.d.ts",
|
|
74
|
+
"development": "./src/sandbox.ts",
|
|
75
|
+
"default": "./dist/sandbox.js"
|
|
76
|
+
},
|
|
72
77
|
"./package.json": "./package.json"
|
|
73
78
|
},
|
|
74
79
|
"files": [
|
|
@@ -96,7 +101,7 @@
|
|
|
96
101
|
"typecheck": "tsc -p tsconfig.json",
|
|
97
102
|
"test": "node --conditions=development --test test/*.test.ts",
|
|
98
103
|
"lint": "eslint .",
|
|
99
|
-
"check": "node scripts/check.ts && node scripts/generate-yaml-reference.ts --check && node scripts/build-llms-full.ts --check && node scripts/build-cookbook-index.ts --check && node scripts/generate-claude-plugin.ts --check",
|
|
104
|
+
"check": "node scripts/check.ts && node scripts/check-trust-model-prose.ts && node scripts/check-guidance-claims.ts && node scripts/generate-yaml-reference.ts --check && node scripts/build-llms-full.ts --check && node scripts/build-cookbook-index.ts --check && node scripts/generate-claude-plugin.ts --check",
|
|
100
105
|
"verify": "npm run lint && npm run typecheck && npm run check && npm run build && npm test",
|
|
101
106
|
"benchmark": "node benchmarks/routing.ts",
|
|
102
107
|
"test:package": "npm run build && node scripts/package-smoke.ts",
|
|
@@ -113,7 +118,9 @@
|
|
|
113
118
|
"docs:plugin": "node scripts/generate-claude-plugin.ts",
|
|
114
119
|
"docs:llms": "node scripts/build-llms-full.ts",
|
|
115
120
|
"docs:cookbook-index": "node scripts/build-cookbook-index.ts",
|
|
121
|
+
"check:downstream-skills": "node scripts/check-downstream-skill-drift.ts",
|
|
116
122
|
"benchmark:bulk": "node benchmarks/bulk.ts",
|
|
123
|
+
"benchmark:sandbox-vs-trusted": "node benchmarks/sandbox-vs-trusted.ts",
|
|
117
124
|
"benchmark:agent": "node benchmarks/agent/run.ts",
|
|
118
125
|
"sync:agents": "node scripts/sync-agent-lists.ts"
|
|
119
126
|
},
|
|
@@ -138,7 +145,7 @@
|
|
|
138
145
|
"globals": "17.12.0",
|
|
139
146
|
"typescript-eslint": "8.70.0"
|
|
140
147
|
},
|
|
141
|
-
"homepage": "https://github.com/jimhoyd-com/urlcode
|
|
148
|
+
"homepage": "https://github.com/jimhoyd-com/urlcode#readme",
|
|
142
149
|
"bugs": {
|
|
143
150
|
"url": "https://github.com/jimhoyd-com/urlcode/issues"
|
|
144
151
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "urlcode",
|
|
3
3
|
"description": "Authoring and operating URLCode projects: the implemented YAML contract, capability limits, deployment and verification commands for the pinned runtime revision.",
|
|
4
|
-
"version": "0.4.0-alpha.
|
|
4
|
+
"version": "0.4.0-alpha.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "jimhoyd-com",
|
|
7
7
|
"url": "https://github.com/jimhoyd-com"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: urlcode-authoring
|
|
3
|
-
description: Author or modify a URLCode project — write and edit urlcode.yaml routes, function and middleware modules, pages, static assets
|
|
3
|
+
description: Author or modify a URLCode project — write and edit urlcode.yaml routes, function and middleware modules, pages, static assets and downloads, then validate and test them. Use whenever a urlcode.yaml file is present or referenced, when the user mentions URLCode, @jimhoyd/urlcode, urlcode routes/handlers/policies/site keys, or asks for redirects or request functions in a URLCode project. Loads the implemented capability matrix so unsupported features are reported as gaps instead of invented.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Authoring URLCode projects
|
|
@@ -11,6 +11,15 @@ validates. Features outside that contract do not silently degrade — they fail
|
|
|
11
11
|
validation. So the cost of guessing is a broken project, and the whole job here
|
|
12
12
|
is to author only what the pinned revision implements and then prove it.
|
|
13
13
|
|
|
14
|
+
## Declarative-first default
|
|
15
|
+
|
|
16
|
+
> Use URLCode's highest-level declarative features whenever possible. Generate custom code only when the framework cannot express the requirement.
|
|
17
|
+
|
|
18
|
+
Check the installed version's primitives, YAML configuration, policies, supported
|
|
19
|
+
extensions and recipes/templates before writing a custom function or middleware.
|
|
20
|
+
Keep necessary custom code focused and report the capability gap; never invent
|
|
21
|
+
fields or bypass target limits or operator grants. See `docs/PROJECT-DIRECTION.md` in the installed runtime.
|
|
22
|
+
|
|
14
23
|
## Read the contract before writing YAML
|
|
15
24
|
|
|
16
25
|
Documentation, schema and runtime must come from the **same revision**. Read from
|
|
@@ -35,8 +44,9 @@ checkout you are working in — never from memory of another version.
|
|
|
35
44
|
tests and the pinned runtime version. Preserve the user's organization,
|
|
36
45
|
naming and unrelated routes.
|
|
37
46
|
- Choose exactly one handler per route — `function`, `redirect`, `respond`,
|
|
38
|
-
`page`, `static`, `download`
|
|
39
|
-
Prefer a native handler when code is
|
|
47
|
+
`page`, `static`, `download`, `conditional`, `proxy` or an `extension` mount
|
|
48
|
+
— plus optional ordered middleware. Prefer a native handler when code is
|
|
49
|
+
unnecessary.
|
|
40
50
|
- Declare each path placeholder as a required string. Paths match whole
|
|
41
51
|
segments: no regex, no greedy captures, no wildcard handlers.
|
|
42
52
|
- Bind typed inputs through `args` or context. There is no `${...}`
|
|
@@ -56,8 +66,14 @@ mistakes that recur:
|
|
|
56
66
|
- No YAML anchors, aliases, template interpolation or remote includes.
|
|
57
67
|
- No recursive includes or glob discovery; includes are explicit.
|
|
58
68
|
- No regex, optional or greedy route segments, and no host-based routing.
|
|
59
|
-
-
|
|
60
|
-
npm
|
|
69
|
+
- `function`/`middleware` routes run trusted and unsandboxed by default: full
|
|
70
|
+
Node, npm, filesystem and `fetch` access, in-process, like any other project
|
|
71
|
+
code. `sandbox: true` opts a route into isolation — reach for it when that
|
|
72
|
+
route's own code warrants it (untrusted input, an unreviewed contribution, a
|
|
73
|
+
particularly sensitive secret), not reflexively on every route. A
|
|
74
|
+
`sandbox: true` route gets a text/JSON `Request`/`Response` sandbox only:
|
|
75
|
+
**no** `fetch`, Node or npm APIs, filesystem, WebSocket, streaming or crypto
|
|
76
|
+
API.
|
|
61
77
|
- No global middleware, Express compatibility or automatic auth.
|
|
62
78
|
- `policies` accepts only `throttle`, `agents`, `security`, `compression` and
|
|
63
79
|
`cache`, every key off unless declared; `hardened` is the only built-in
|
|
@@ -68,9 +84,9 @@ mistakes that recur:
|
|
|
68
84
|
only and off unless declared; a declared route at the same path wins. Its
|
|
69
85
|
generated routes count toward `--expect-routes`, and `site.sitemap` needs
|
|
70
86
|
`--origin` on every command that activates the project.
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
- There is no native `link` handler or `dynamicLinks` project flag. Stored
|
|
88
|
+
short links are moving to a future `urlcode-dynamic-link` extension package,
|
|
89
|
+
not yet published; report that as a gap, never invent a `link` field.
|
|
74
90
|
- Infrastructure (proxy ranges, storage URLs, vendor rule identifiers) is an
|
|
75
91
|
operator flag, never route YAML.
|
|
76
92
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: urlcode-operations
|
|
3
|
-
description: Deploy, verify, monitor and operate a URLCode project — process/container deployment, release readiness, verifying a live deployment against the project, capacity/audit/benchmark, observability, DDoS/overload resilience, and
|
|
3
|
+
description: Deploy, verify, monitor and operate a URLCode project — process/container deployment, release readiness, verifying a live deployment against the project, capacity/audit/benchmark, observability, DDoS/overload resilience, and operator binding grants. Use when the user asks to deploy, check readiness, verify a running deployment, size/benchmark a project, monitor it, plan for overload, or manage bindings. Reports operational limits and unimplemented capabilities as gaps instead of inventing mitigations.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Operating a URLCode deployment
|
|
@@ -30,9 +30,7 @@ another version.
|
|
|
30
30
|
overload and DDoS; what layer each defense belongs to.
|
|
31
31
|
6. `docs/MONITORING.md` and `docs/OBSERVABILITY.md` — health/ready probes,
|
|
32
32
|
logs, metrics format, what is and is not exported.
|
|
33
|
-
7. `docs/
|
|
34
|
-
policy shape, scope, loopback-only binding.
|
|
35
|
-
8. `docs/POLICIES.md` and `docs/FUNCTION-SECURITY.md` — per-target policy
|
|
33
|
+
7. `docs/POLICIES.md` and `docs/FUNCTION-SECURITY.md` — per-target policy
|
|
36
34
|
support and the operator binding-grant process, needed whenever a
|
|
37
35
|
deployment or verification step touches either.
|
|
38
36
|
|
|
@@ -71,8 +69,8 @@ urlcode verify-deployment --project ./my-links --target https://links.example \
|
|
|
71
69
|
Run the actual commands and report actual results, never "should work" or
|
|
72
70
|
"should be reachable". `verify-deployment` needs a real target; do not
|
|
73
71
|
simulate its output. In a runtime checkout, substitute `node src/cli.ts` for
|
|
74
|
-
`urlcode`. Pass `--policy
|
|
75
|
-
|
|
72
|
+
`urlcode`. Pass `--policy` where a snapshot needs bindings already reviewed
|
|
73
|
+
by the operator.
|
|
76
74
|
|
|
77
75
|
## Hard limits — report these as gaps, never invent around them
|
|
78
76
|
|
|
@@ -84,12 +82,9 @@ already reviewed by the operator.
|
|
|
84
82
|
- `verify-deployment` has no infrastructure access, uses no credential,
|
|
85
83
|
follows no redirect and offers no `--insecure`. It cannot check anything a
|
|
86
84
|
read-only HTTP probe cannot observe.
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- A management credentials policy is operator-owned, outside the application,
|
|
91
|
-
never in YAML or Git, at most 64 KiB, mode 600, at most 128 credentials with
|
|
92
|
-
explicit collection/action allowlists — no wildcards.
|
|
85
|
+
- Core has no durable store and no private management API of its own; stored
|
|
86
|
+
short links are moving to a future `urlcode-dynamic-link` extension
|
|
87
|
+
package, not yet published.
|
|
93
88
|
- Sandbox concurrency, worker slots and execution deadlines are shared across
|
|
94
89
|
every programmable route in a snapshot; there is no per-route fairness or
|
|
95
90
|
reserved capacity, and awaiting a guest timer still occupies a slot.
|
|
@@ -102,10 +97,9 @@ responsibility that covers it instead of inventing a flag.
|
|
|
102
97
|
|
|
103
98
|
## Boundaries
|
|
104
99
|
|
|
105
|
-
- Never generate or approve an operator binding grant
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
real secret.
|
|
100
|
+
- Never generate or approve an operator binding grant on the user's behalf.
|
|
101
|
+
That is the operator's own reviewed decision; produce the shape and let
|
|
102
|
+
them fill in and store the real secret.
|
|
109
103
|
- Keep every credential, token and policy file out of source, examples and
|
|
110
104
|
Git. A synthetic example value is fine; a real one is never committed.
|
|
111
105
|
- Do not deploy, expose a service, rotate a credential, or run
|
|
@@ -3,7 +3,7 @@ description: JSON endpoint protected by the operator-installed auth extension th
|
|
|
3
3
|
tags: [auth, authenticated, protected, signed-in, bearer, json, api, function, extension, "401", private]
|
|
4
4
|
complexity: advanced
|
|
5
5
|
capabilities: [enabled, extension, function, methods, policies.extensions]
|
|
6
|
-
targets: {self-hosted:
|
|
6
|
+
targets: {self-hosted: conditional, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
services:
|
|
9
9
|
- name: auth extension
|
|
@@ -3,7 +3,7 @@ description: Validate a JSON contact message in the sandbox and notify an operat
|
|
|
3
3
|
tags: [contact, form, message, email, post, json, validation, signal, notify, hook, egress, "422"]
|
|
4
4
|
complexity: intermediate
|
|
5
5
|
capabilities: [enabled, function, methods, request.body, response.headers, signals]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
services:
|
|
9
9
|
- name: hook endpoint
|
|
@@ -3,7 +3,7 @@ description: JSON endpoint for one allowed browser origin; middleware answers pr
|
|
|
3
3
|
tags: [cors, preflight, options, browser, origin, api, json, middleware, access-control, vary]
|
|
4
4
|
complexity: intermediate
|
|
5
5
|
capabilities: [enabled, function, methods, middleware, response.headers]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
inputs:
|
|
9
9
|
- name: allowedOrigins
|
|
@@ -3,7 +3,7 @@ description: Plain-text liveness and JSON readiness answers served natively with
|
|
|
3
3
|
tags: [health, status, readiness, liveness, uptime, probe, monitoring, respond, native, json]
|
|
4
4
|
complexity: starter
|
|
5
5
|
capabilities: [enabled, methods, respond, response.headers]
|
|
6
|
-
targets: {self-hosted: compatible, aws: compatible, vercel: compatible, cloudflare: compatible}
|
|
6
|
+
targets: {self-hosted: compatible, aws: compatible, vercel: compatible, cloudflare: compatible, static: refused}
|
|
7
7
|
routes: 2
|
|
8
8
|
inputs:
|
|
9
9
|
- name: service
|
|
@@ -3,7 +3,7 @@ description: Bounded JSON request body echoed back by a sandboxed function.
|
|
|
3
3
|
tags: [json, api, post, echo, function, body, validation, sandbox]
|
|
4
4
|
complexity: starter
|
|
5
5
|
capabilities: [enabled, function, methods, request.body]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
inputs:
|
|
9
9
|
- name: handler
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// Sticky A/B bucketing through a cookie, as on Vercel or Cloudflare edge examples.
|
|
2
2
|
// Bucket b gets a different destination; everyone keeps their bucket for a week.
|
|
3
|
+
// `Response.redirect()`'s headers are immutable (per the Fetch standard a
|
|
4
|
+
// trusted route's real `Response` enforces this, unlike the sandbox's guest
|
|
5
|
+
// API), so build that branch's headers up front instead of mutating the
|
|
6
|
+
// result afterward.
|
|
3
7
|
function cookie(request, name) {
|
|
4
8
|
for (const part of (request.headers.get('cookie') || '').split(';')) {
|
|
5
9
|
const [key, ...rest] = part.trim().split('=');
|
|
@@ -12,8 +16,14 @@ export default async function bucket(request, context, next) {
|
|
|
12
16
|
const fresh = assigned !== 'a' && assigned !== 'b';
|
|
13
17
|
if (fresh) assigned = Math.random() < 0.5 ? 'a' : 'b';
|
|
14
18
|
context.state.bucket = assigned;
|
|
15
|
-
const
|
|
19
|
+
const setCookie = 'bucket=' + assigned + '; Path=/; Max-Age=604800; SameSite=Lax';
|
|
20
|
+
if (assigned === 'b') {
|
|
21
|
+
const headers = new Headers({ location: context.env.VARIANT_URL, vary: 'cookie' });
|
|
22
|
+
if (fresh) headers.append('set-cookie', setCookie);
|
|
23
|
+
return new Response(null, { status: 302, headers });
|
|
24
|
+
}
|
|
25
|
+
const response = await next();
|
|
16
26
|
response.headers.set('vary', 'cookie');
|
|
17
|
-
if (fresh) response.headers.append('set-cookie',
|
|
27
|
+
if (fresh) response.headers.append('set-cookie', setCookie);
|
|
18
28
|
return response;
|
|
19
29
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// Language redirect from Accept-Language, like Next.js i18n middleware. Only
|
|
2
2
|
// languages listed in LOCALES are chosen; the native redirect is the default.
|
|
3
|
+
// `Response.redirect()`'s headers are immutable (a trusted route's real
|
|
4
|
+
// `Response` enforces the Fetch standard here, unlike the sandbox's guest
|
|
5
|
+
// API), so that branch builds its own `Response` with headers up front.
|
|
3
6
|
export default async function locale(request, context, next) {
|
|
4
7
|
const supported = (context.env.LOCALES || '').split(/\s+/).filter(Boolean);
|
|
5
8
|
const ranked = (request.headers.get('accept-language') || '').split(',').map((part, index) => {
|
|
@@ -8,9 +11,10 @@ export default async function locale(request, context, next) {
|
|
|
8
11
|
return {lang: tag.trim().toLowerCase().split('-')[0], q: q ? Number(q.slice(2)) || 0 : 1, index};
|
|
9
12
|
}).filter(p => p.q > 0).sort((a, b) => b.q - a.q || a.index - b.index);
|
|
10
13
|
const chosen = ranked.find(p => supported.includes(p.lang))?.lang;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
if (chosen && chosen !== supported[0]) {
|
|
15
|
+
return new Response(null, { status: 302, headers: { location: context.env.SITE + '/' + chosen + '/welcome', vary: 'accept-language' } });
|
|
16
|
+
}
|
|
17
|
+
const response = await next();
|
|
14
18
|
response.headers.set('vary', 'accept-language');
|
|
15
19
|
return response;
|
|
16
20
|
}
|
|
@@ -3,7 +3,7 @@ description: Fourteen reusable middleware patterns around fifteen routes, mirror
|
|
|
3
3
|
tags: [middleware, auth, bearer, basic, cors, tracing, request-id, errors, etag, caching, maintenance, negotiation, locale, referer, method-override, envelope, validation, debug, bucket, experiment]
|
|
4
4
|
complexity: advanced
|
|
5
5
|
capabilities: [bindings, download, enabled, function, methods, middleware, parameters, redirect, request.body, respond]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 15
|
|
8
8
|
inputs:
|
|
9
9
|
- name: credentials
|
|
@@ -3,7 +3,7 @@ description: Native attachment download that only the operator-installed auth ex
|
|
|
3
3
|
tags: [download, attachment, protected, auth, authenticated, file, private, extension, content-disposition, "401"]
|
|
4
4
|
complexity: advanced
|
|
5
5
|
capabilities: [download, enabled, extension, methods, policies.extensions]
|
|
6
|
-
targets: {self-hosted:
|
|
6
|
+
targets: {self-hosted: conditional, aws: conditional, vercel: conditional, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
services:
|
|
9
9
|
- name: auth extension
|
|
@@ -3,7 +3,7 @@ description: Permanent redirect that forwards only an allowlisted query key.
|
|
|
3
3
|
tags: [redirect, permanent, "301", query, passthrough, documentation, native]
|
|
4
4
|
complexity: starter
|
|
5
5
|
capabilities: [enabled, methods, redirect]
|
|
6
|
-
targets: {self-hosted: compatible, aws: compatible, vercel: compatible, cloudflare: compatible}
|
|
6
|
+
targets: {self-hosted: compatible, aws: compatible, vercel: compatible, cloudflare: compatible, static: compatible}
|
|
7
7
|
routes: 1
|
|
8
8
|
inputs:
|
|
9
9
|
- name: destination
|
|
@@ -3,7 +3,7 @@ description: A native static site (home page and an assets directory) next to on
|
|
|
3
3
|
tags: [static, site, page, html, assets, css, api, json, function, cache-control, website]
|
|
4
4
|
complexity: intermediate
|
|
5
5
|
capabilities: [enabled, function, methods, page, response.headers, static]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 3
|
|
8
8
|
inputs:
|
|
9
9
|
- name: pages
|
|
@@ -4,4 +4,5 @@ Run `urlcode build-typescript --project . --out ../hello-built` with a new outpu
|
|
|
4
4
|
directory, then `urlcode validate --local --project ../hello-built` and
|
|
5
5
|
`urlcode serve --project ../hello-built`. GET `/hello` returns JSON.
|
|
6
6
|
TypeScript is transpiled ahead of time. The runtime executes only the emitted
|
|
7
|
-
JavaScript in QuickJS/WASM
|
|
7
|
+
JavaScript, in QuickJS/WASM for a `sandbox: true` route and in-process for a
|
|
8
|
+
trusted one. The build does not type-check or read tsconfig.json.
|
|
@@ -3,7 +3,7 @@ description: Typed guest function transpiled ahead of time; only the emitted Jav
|
|
|
3
3
|
tags: [typescript, function, build, typed, compile, sandbox]
|
|
4
4
|
complexity: intermediate
|
|
5
5
|
capabilities: [enabled, function, methods]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
inputs:
|
|
9
9
|
- name: handler
|
|
@@ -5,7 +5,11 @@ Run `urlcode validate --local --project .`, `urlcode test --project .` and
|
|
|
5
5
|
|
|
6
6
|
`POST /webhook` accepts at most 64 KiB of `application/json`. The runtime
|
|
7
7
|
rejects other methods (405), other content types (415), oversized bodies (413)
|
|
8
|
-
and malformed JSON (400) before the sandbox runs. The
|
|
8
|
+
and malformed JSON (400) before the sandbox runs. The route declares
|
|
9
|
+
`sandbox: true`: functions/middleware run trusted by default, but a
|
|
10
|
+
third-party sender's payload is exactly the input a project doesn't fully
|
|
11
|
+
trust, so this recipe isolates parsing it (docs/FUNCTION-SECURITY.md). The
|
|
12
|
+
function then requires an
|
|
9
13
|
`X-Webhook-Event` header and a JSON object carrying a string `id`, and answers
|
|
10
14
|
`202 {"received":true,...}`.
|
|
11
15
|
|
|
@@ -3,7 +3,7 @@ description: Accept a bounded JSON event that names its type in a header, check
|
|
|
3
3
|
tags: [webhook, receiver, event, post, json, body, "202", callback, ingest, function]
|
|
4
4
|
complexity: starter
|
|
5
5
|
capabilities: [enabled, function, methods, request.body, response.headers]
|
|
6
|
-
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
|
|
6
|
+
targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused, static: refused}
|
|
7
7
|
routes: 1
|
|
8
8
|
inputs:
|
|
9
9
|
- name: shape check
|
|
@@ -24,3 +24,4 @@ behavior:
|
|
|
24
24
|
- a missing event header answers 400; a body that is not an object with a string id answers 422
|
|
25
25
|
- other methods 405, other content types 415, oversized bodies 413 and malformed JSON 400 before the sandbox runs
|
|
26
26
|
- the guest has no crypto or network API, so signatures are not verified here; put signed webhooks behind an operator extension or trusted host
|
|
27
|
+
- "the route declares sandbox: true, isolating the third-party payload from the trusted-by-default execution every other function/middleware route gets"
|
|
@@ -11,6 +11,13 @@ routes:
|
|
|
11
11
|
format: json
|
|
12
12
|
function:
|
|
13
13
|
source: functions/receive.mjs
|
|
14
|
+
# A third-party sender's payload is exactly the kind of input this
|
|
15
|
+
# project does not fully trust (docs/AI-AUTHORING.md, "Deciding when a
|
|
16
|
+
# route needs sandbox: true"), even after body/content-type validation:
|
|
17
|
+
# isolate parsing it from the rest of the process.
|
|
18
|
+
sandbox: true
|
|
19
|
+
sandboxReason: >-
|
|
20
|
+
Third-party webhook payload; isolate parsing it even after body/content-type validation.
|
|
14
21
|
response:
|
|
15
22
|
headers:
|
|
16
23
|
Cache-Control: no-store
|
|
@@ -45,12 +45,13 @@
|
|
|
45
45
|
"description": "Derived: the capability preflight verdict per target. compatible means no issue; otherwise the strongest issue (refused, unknown, conditional).",
|
|
46
46
|
"type": "object",
|
|
47
47
|
"additionalProperties": false,
|
|
48
|
-
"required": ["self-hosted", "aws", "vercel", "cloudflare"],
|
|
48
|
+
"required": ["self-hosted", "aws", "vercel", "cloudflare", "static"],
|
|
49
49
|
"properties": {
|
|
50
50
|
"self-hosted": {"$ref": "#/$defs/verdict"},
|
|
51
51
|
"aws": {"$ref": "#/$defs/verdict"},
|
|
52
52
|
"vercel": {"$ref": "#/$defs/verdict"},
|
|
53
|
-
"cloudflare": {"$ref": "#/$defs/verdict"}
|
|
53
|
+
"cloudflare": {"$ref": "#/$defs/verdict"},
|
|
54
|
+
"static": {"$ref": "#/$defs/verdict"}
|
|
54
55
|
}
|
|
55
56
|
},
|
|
56
57
|
"routes": {
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
"additionalProperties": false,
|
|
82
83
|
"required": ["kind", "description"],
|
|
83
84
|
"properties": {
|
|
84
|
-
"kind": {"enum": ["extension", "signals", "proxy", "env", "secret", "
|
|
85
|
+
"kind": {"enum": ["extension", "signals", "proxy", "env", "secret", "origin"]},
|
|
85
86
|
"description": {"type": "string", "minLength": 1, "maxLength": 300}
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
"uniqueItems": true,
|
|
23
23
|
"maxItems": 256
|
|
24
24
|
},
|
|
25
|
-
"dynamicLinks": {
|
|
26
|
-
"type": "boolean",
|
|
27
|
-
"default": false,
|
|
28
|
-
"description": "Entry-point opt-in for live stored-link routes. Does not enable guest storage or management access."
|
|
29
|
-
},
|
|
30
25
|
"policies": {
|
|
31
26
|
"$ref": "#/$defs/policies"
|
|
32
27
|
},
|
|
@@ -346,6 +341,16 @@
|
|
|
346
341
|
"enabled": {
|
|
347
342
|
"type": "boolean"
|
|
348
343
|
},
|
|
344
|
+
"sandbox": {
|
|
345
|
+
"type": "boolean",
|
|
346
|
+
"default": false,
|
|
347
|
+
"description": "Run this route's function/middleware in the isolated QuickJS/WASM worker pool instead of the trusted, in-process default. false or absent (the default) means trusted, unsandboxed, direct host-process execution."
|
|
348
|
+
},
|
|
349
|
+
"sandboxReason": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"maxLength": 500,
|
|
352
|
+
"description": "Optional justification for this route's sandbox decision, whether sandbox is true or false: why it needs isolation, or why it is safe to trust. Never inferred or enforced; surfaced verbatim by explain/context/manifest."
|
|
353
|
+
},
|
|
349
354
|
"expires": {
|
|
350
355
|
"type": "string"
|
|
351
356
|
},
|
|
@@ -882,37 +887,6 @@
|
|
|
882
887
|
]
|
|
883
888
|
}
|
|
884
889
|
},
|
|
885
|
-
"link": {
|
|
886
|
-
"type": "object",
|
|
887
|
-
"properties": {
|
|
888
|
-
"collection": {
|
|
889
|
-
"type": "string",
|
|
890
|
-
"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
|
|
891
|
-
},
|
|
892
|
-
"code": {
|
|
893
|
-
"type": "object",
|
|
894
|
-
"properties": {
|
|
895
|
-
"from": {
|
|
896
|
-
"const": "path"
|
|
897
|
-
},
|
|
898
|
-
"name": {
|
|
899
|
-
"type": "string",
|
|
900
|
-
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
901
|
-
}
|
|
902
|
-
},
|
|
903
|
-
"required": [
|
|
904
|
-
"from",
|
|
905
|
-
"name"
|
|
906
|
-
],
|
|
907
|
-
"additionalProperties": false
|
|
908
|
-
}
|
|
909
|
-
},
|
|
910
|
-
"required": [
|
|
911
|
-
"collection",
|
|
912
|
-
"code"
|
|
913
|
-
],
|
|
914
|
-
"additionalProperties": false
|
|
915
|
-
},
|
|
916
890
|
"policies": {
|
|
917
891
|
"$ref": "#/$defs/policies"
|
|
918
892
|
},
|
|
@@ -964,6 +938,10 @@
|
|
|
964
938
|
"$ref": "#/$defs/routeAuth"
|
|
965
939
|
}
|
|
966
940
|
]
|
|
941
|
+
},
|
|
942
|
+
"cache": {
|
|
943
|
+
"description": "Short form for policies.cache: the same object, expanded to policies.cache before anything else reads the project. Refused alongside policies.cache; use one form.",
|
|
944
|
+
"$ref": "#/$defs/policyCache"
|
|
967
945
|
}
|
|
968
946
|
},
|
|
969
947
|
"required": [],
|
|
@@ -999,11 +977,6 @@
|
|
|
999
977
|
"respond"
|
|
1000
978
|
]
|
|
1001
979
|
},
|
|
1002
|
-
{
|
|
1003
|
-
"required": [
|
|
1004
|
-
"link"
|
|
1005
|
-
]
|
|
1006
|
-
},
|
|
1007
980
|
{
|
|
1008
981
|
"required": [
|
|
1009
982
|
"conditional"
|