@jimhoyd/urlcode 0.3.0 → 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.
Files changed (380) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +122 -0
  2. package/.claude/skills/urlcode-operations/SKILL.md +108 -0
  3. package/.claude-plugin/marketplace.json +18 -0
  4. package/CONTRIBUTING.md +30 -2
  5. package/README.md +195 -255
  6. package/ROADMAP.md +143 -15
  7. package/SECURITY.md +31 -9
  8. package/dist/BUILD-MANIFEST.json +72 -47
  9. package/dist/adapters.js +4 -23
  10. package/dist/agent-lists.js +1 -1
  11. package/dist/agents-guide.js +113 -0
  12. package/dist/authoring-files.js +60 -0
  13. package/dist/authoring.js +11 -1
  14. package/dist/aws.js +4 -3
  15. package/dist/build-cloudflare.js +11 -24
  16. package/dist/build-static.js +134 -0
  17. package/dist/bulk.js +37 -0
  18. package/dist/capabilities.js +262 -0
  19. package/dist/capability-query.js +71 -0
  20. package/dist/catalog.js +105 -0
  21. package/dist/cli.js +165 -34
  22. package/dist/client-address.js +1 -1
  23. package/dist/compliance-rules/baseline.js +9 -17
  24. package/dist/compliance-rules/privacy.js +7 -18
  25. package/dist/compliance-rules/shared.js +0 -2
  26. package/dist/compliance-rules/strict.js +5 -5
  27. package/dist/compliance.js +6 -8
  28. package/dist/conditions.js +88 -0
  29. package/dist/config.js +69 -6
  30. package/dist/context.js +155 -0
  31. package/dist/ecosystem-cli.js +88 -0
  32. package/dist/egress.js +98 -0
  33. package/dist/examples.js +92 -0
  34. package/dist/explain-cli.js +64 -0
  35. package/dist/explain.js +131 -0
  36. package/dist/extensions.js +231 -0
  37. package/dist/function-sources.js +49 -5
  38. package/dist/function-worker.js +3 -1
  39. package/dist/functions.js +84 -13
  40. package/dist/guest-api.js +29 -3
  41. package/dist/index.js +40 -6
  42. package/dist/init-with.js +165 -0
  43. package/dist/interchange-cli.js +42 -0
  44. package/dist/interchange.js +189 -0
  45. package/dist/manifest.js +109 -0
  46. package/dist/match.js +2 -2
  47. package/dist/mcp-authoring.js +147 -0
  48. package/dist/mcp.js +97 -0
  49. package/dist/observability.js +7 -21
  50. package/dist/operator-host.js +29 -0
  51. package/dist/plugins.js +12 -0
  52. package/dist/policies/agents.js +2 -2
  53. package/dist/policies/cache.js +8 -3
  54. package/dist/policies/compression.js +2 -1
  55. package/dist/policies/security.js +0 -0
  56. package/dist/policies.js +1 -1
  57. package/dist/policy.js +56 -15
  58. package/dist/prerender.js +100 -41
  59. package/dist/project-tests.js +3 -3
  60. package/dist/provider-verification.js +92 -0
  61. package/dist/proxy.js +44 -0
  62. package/dist/readiness.js +34 -11
  63. package/dist/recipes.js +41 -0
  64. package/dist/route-diff.js +106 -0
  65. package/dist/router.js +45 -7
  66. package/dist/runtime.js +164 -64
  67. package/dist/sandbox.js +48 -0
  68. package/dist/scaffold.js +0 -0
  69. package/dist/schema-query.js +62 -0
  70. package/dist/scripts/operational-drills.js +12 -54
  71. package/dist/server.js +3 -29
  72. package/dist/signals.js +24 -0
  73. package/dist/site.js +0 -0
  74. package/dist/tooling.js +96 -0
  75. package/dist/trusted-functions.js +210 -0
  76. package/dist/types/adapters.d.ts +7 -4
  77. package/dist/types/agent-lists.d.ts +0 -1
  78. package/dist/types/agents-guide.d.ts +17 -0
  79. package/dist/types/authoring-files.d.ts +10 -0
  80. package/dist/types/aws.d.ts +3 -1
  81. package/dist/types/build-cloudflare.d.ts +1 -0
  82. package/dist/types/build-static.d.ts +43 -0
  83. package/dist/types/bulk.d.ts +27 -0
  84. package/dist/types/capabilities.d.ts +64 -0
  85. package/dist/types/capability-query.d.ts +24 -0
  86. package/dist/types/catalog.d.ts +65 -0
  87. package/dist/types/client-address.d.ts +0 -1
  88. package/dist/types/compliance-rules/baseline.d.ts +1 -9
  89. package/dist/types/compliance-rules/privacy.d.ts +1 -4
  90. package/dist/types/compliance-rules/shared.d.ts +0 -2
  91. package/dist/types/compliance-rules/strict.d.ts +0 -5
  92. package/dist/types/compliance.d.ts +0 -3
  93. package/dist/types/conditions.d.ts +19 -0
  94. package/dist/types/config.d.ts +21 -2
  95. package/dist/types/context.d.ts +66 -0
  96. package/dist/types/ecosystem-cli.d.ts +17 -0
  97. package/dist/types/egress.d.ts +46 -0
  98. package/dist/types/examples.d.ts +50 -0
  99. package/dist/types/explain-cli.d.ts +11 -0
  100. package/dist/types/explain.d.ts +95 -0
  101. package/dist/types/extensions.d.ts +177 -0
  102. package/dist/types/function-sources.d.ts +9 -0
  103. package/dist/types/functions.d.ts +48 -5
  104. package/dist/types/guest-api.d.ts +1 -0
  105. package/dist/types/index.d.ts +36 -6
  106. package/dist/types/init-with.d.ts +30 -0
  107. package/dist/types/interchange-cli.d.ts +16 -0
  108. package/dist/types/interchange.d.ts +42 -0
  109. package/dist/types/manifest.d.ts +79 -0
  110. package/dist/types/match.d.ts +1 -0
  111. package/dist/types/mcp-authoring.d.ts +92 -0
  112. package/dist/types/mcp.d.ts +12 -0
  113. package/dist/types/observability.d.ts +3 -14
  114. package/dist/types/operator-host.d.ts +8 -0
  115. package/dist/types/plugins.d.ts +2 -0
  116. package/dist/types/policies/agents.d.ts +0 -2
  117. package/dist/types/policies/compression.d.ts +2 -0
  118. package/dist/types/policies/security.d.ts +0 -1
  119. package/dist/types/policy.d.ts +15 -4
  120. package/dist/types/project-tests.d.ts +3 -2
  121. package/dist/types/provider-verification.d.ts +53 -0
  122. package/dist/types/proxy.d.ts +21 -0
  123. package/dist/types/readiness.d.ts +10 -3
  124. package/dist/types/recipes.d.ts +30 -0
  125. package/dist/types/route-diff.d.ts +27 -0
  126. package/dist/types/router.d.ts +2 -1
  127. package/dist/types/runtime.d.ts +11 -27
  128. package/dist/types/sandbox.d.ts +12 -0
  129. package/dist/types/scaffold.d.ts +0 -2
  130. package/dist/types/schema-query.d.ts +12 -0
  131. package/dist/types/server.d.ts +1 -4
  132. package/dist/types/signals.d.ts +25 -0
  133. package/dist/types/site.d.ts +0 -1
  134. package/dist/types/tooling.d.ts +115 -0
  135. package/dist/types/trusted-functions.d.ts +29 -0
  136. package/dist/types/types.d.ts +71 -7
  137. package/dist/types/typescript-authoring.d.ts +12 -0
  138. package/dist/types/vercel.d.ts +3 -1
  139. package/dist/types/verify-deployment.d.ts +47 -0
  140. package/dist/types.js +37 -5
  141. package/dist/typescript-authoring.js +142 -0
  142. package/dist/vercel.js +4 -3
  143. package/dist/verify-deployment.js +270 -0
  144. package/docs/AI-AUTHORING.md +232 -15
  145. package/docs/AWS.md +4 -4
  146. package/docs/BEST-PRACTICES.md +3 -2
  147. package/docs/BULK.md +79 -0
  148. package/docs/CAPABILITIES.md +192 -0
  149. package/docs/CAPACITY.md +129 -32
  150. package/docs/CI.md +142 -0
  151. package/docs/CLOUDFLARE.md +1 -2
  152. package/docs/COMPLIANCE.md +6 -9
  153. package/docs/CONDITIONS.md +74 -0
  154. package/docs/DEPLOYMENT-CHECKS.md +108 -0
  155. package/docs/EGRESS.md +125 -0
  156. package/docs/EXTENSIONS.md +398 -0
  157. package/docs/FRAMEWORK.md +198 -0
  158. package/docs/FUNCTION-SECURITY.md +129 -32
  159. package/docs/INSTALL.md +45 -12
  160. package/docs/INTERCHANGE.md +134 -0
  161. package/docs/LOAD-TESTING.md +4 -4
  162. package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
  163. package/docs/MIDDLEWARE.md +29 -16
  164. package/docs/MONITORING.md +2 -19
  165. package/docs/NEXT-PHASE-PLAN.md +98 -0
  166. package/docs/NEXT-STEPS.md +634 -0
  167. package/docs/OBSERVABILITY.md +11 -18
  168. package/docs/OPEN-DECISIONS.md +212 -0
  169. package/docs/OPERATIONAL-PROOF.md +30 -31
  170. package/docs/OPERATIONS.md +29 -35
  171. package/docs/PLUGINS.md +37 -0
  172. package/docs/POLICIES.md +23 -309
  173. package/docs/PRERENDER.md +41 -1
  174. package/docs/PROJECT-DIRECTION.md +75 -8
  175. package/docs/PROVIDER-VERIFICATION.md +84 -0
  176. package/docs/READINESS.md +21 -1
  177. package/docs/README.md +87 -34
  178. package/docs/RECIPES.md +99 -0
  179. package/docs/RELEASE-READINESS.md +57 -35
  180. package/docs/RELEASE-SECURITY.md +116 -7
  181. package/docs/RESILIENCE.md +16 -15
  182. package/docs/ROUTING.md +8 -10
  183. package/docs/SANDBOX-REVIEW.md +19 -6
  184. package/docs/SCAFFOLDING.md +0 -2
  185. package/docs/SECURITY-AUDIT.md +41 -1
  186. package/docs/SPECIFICATION.md +150 -29
  187. package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
  188. package/docs/SPIKE-BUSINESS-SUITE.md +1021 -0
  189. package/docs/SPIKE-CORE-LAYERING.md +337 -0
  190. package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
  191. package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
  192. package/docs/SPIKE-EXTENSIONS.md +6 -0
  193. package/docs/SPIKE-LAMBDA-COMPILE.md +201 -0
  194. package/docs/SPIKE-MONOREPO.md +322 -0
  195. package/docs/STANDARDS.md +150 -142
  196. package/docs/STARTERS.md +21 -1
  197. package/docs/STATIC.md +94 -0
  198. package/docs/TOOLING.md +295 -0
  199. package/docs/TUNNELS.md +0 -3
  200. package/docs/TYPESCRIPT-AUTHORING.md +82 -0
  201. package/docs/TYPESCRIPT.md +25 -4
  202. package/docs/USABILITY-REVIEW.md +129 -0
  203. package/docs/VERCEL.md +4 -5
  204. package/docs/VERSION-ALIGNMENT.md +205 -0
  205. package/docs/YAML-GUIDE.md +15 -479
  206. package/docs/YAML-REFERENCE.md +143 -22
  207. package/docs/policies/agents.md +1 -1
  208. package/docs/policies/cache.md +13 -0
  209. package/docs/policies/contract.md +52 -0
  210. package/docs/policies/hardened.md +56 -0
  211. package/docs/policies/interoperability.md +169 -0
  212. package/docs/policies/operations.md +45 -0
  213. package/docs/yaml/assets.md +36 -0
  214. package/docs/yaml/conditions.md +20 -0
  215. package/docs/yaml/functions.md +160 -0
  216. package/docs/yaml/middleware.md +29 -0
  217. package/docs/yaml/organization.md +74 -0
  218. package/docs/yaml/policies.md +37 -0
  219. package/docs/yaml/redirects.md +64 -0
  220. package/docs/yaml/responses.md +57 -0
  221. package/docs/yaml/site.md +24 -0
  222. package/examples/assets/example.yaml +17 -0
  223. package/examples/aws/example.yaml +20 -0
  224. package/examples/cloudflare/example.yaml +19 -0
  225. package/examples/compliance/example.yaml +11 -0
  226. package/examples/conditions/README.md +12 -0
  227. package/examples/conditions/example.yaml +19 -0
  228. package/examples/conditions/tests/requests.json +13 -0
  229. package/examples/conditions/urlcode.yaml +24 -0
  230. package/examples/cookbook/README.md +8 -4
  231. package/examples/cookbook/example.yaml +17 -0
  232. package/examples/cookbook/functions/catalog.mjs +3 -0
  233. package/examples/cookbook/functions/fail.mjs +4 -0
  234. package/examples/cookbook/functions/items.mjs +3 -0
  235. package/examples/cookbook/functions/profile.mjs +3 -0
  236. package/examples/cookbook/functions/resource.mjs +3 -0
  237. package/examples/cookbook/functions/status.mjs +3 -0
  238. package/examples/cookbook/middleware/auth.mjs +48 -0
  239. package/examples/cookbook/middleware/body.mjs +15 -0
  240. package/examples/cookbook/middleware/bucket.mjs +29 -0
  241. package/examples/cookbook/middleware/cors.mjs +21 -0
  242. package/examples/cookbook/middleware/debug.mjs +13 -0
  243. package/examples/cookbook/middleware/envelope.mjs +11 -0
  244. package/examples/cookbook/middleware/errors.mjs +11 -0
  245. package/examples/cookbook/middleware/etag.mjs +18 -0
  246. package/examples/cookbook/middleware/locale.mjs +20 -0
  247. package/examples/cookbook/middleware/maintenance.mjs +10 -0
  248. package/examples/cookbook/middleware/methods.mjs +15 -0
  249. package/examples/cookbook/middleware/negotiate.mjs +20 -0
  250. package/examples/cookbook/middleware/referer.mjs +12 -0
  251. package/examples/cookbook/middleware/request-id.mjs +16 -0
  252. package/examples/cookbook/route-index.json +676 -0
  253. package/examples/cookbook/routes/middleware.yaml +126 -0
  254. package/examples/cookbook/tests/requests.json +526 -0
  255. package/examples/cookbook/urlcode.yaml +1 -0
  256. package/examples/egress/README.md +22 -0
  257. package/examples/egress/example.yaml +19 -0
  258. package/examples/egress/urlcode.yaml +19 -0
  259. package/examples/extensions/README.md +7 -0
  260. package/examples/extensions/example.yaml +21 -0
  261. package/examples/extensions/urlcode.yaml +25 -0
  262. package/examples/monitoring/example.yaml +8 -0
  263. package/examples/prerender/README.md +2 -2
  264. package/examples/prerender/example.yaml +16 -0
  265. package/examples/provider-conformance/README.md +12 -0
  266. package/examples/provider-conformance/example.yaml +14 -0
  267. package/examples/provider-conformance/urlcode.yaml +34 -0
  268. package/examples/tunnel/example.yaml +8 -0
  269. package/examples/vercel/example.yaml +19 -0
  270. package/llms-full.txt +3084 -0
  271. package/llms.txt +61 -21
  272. package/package.json +36 -7
  273. package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
  274. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +122 -0
  275. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +108 -0
  276. package/recipes/authenticated-json-api/README.md +51 -0
  277. package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
  278. package/recipes/authenticated-json-api/recipe.yaml +34 -0
  279. package/recipes/authenticated-json-api/tests/requests.json +39 -0
  280. package/recipes/authenticated-json-api/urlcode.yaml +12 -0
  281. package/recipes/contact-form/README.md +25 -0
  282. package/recipes/contact-form/functions/contact.mjs +17 -0
  283. package/recipes/contact-form/recipe.yaml +33 -0
  284. package/recipes/contact-form/tests/requests.json +47 -0
  285. package/recipes/contact-form/urlcode.yaml +18 -0
  286. package/recipes/cors-api/README.md +16 -0
  287. package/recipes/cors-api/functions/items.mjs +3 -0
  288. package/recipes/cors-api/middleware/cors.mjs +21 -0
  289. package/recipes/cors-api/recipe.yaml +26 -0
  290. package/recipes/cors-api/tests/requests.json +65 -0
  291. package/recipes/cors-api/urlcode.yaml +12 -0
  292. package/recipes/health-page/README.md +13 -0
  293. package/recipes/health-page/recipe.yaml +23 -0
  294. package/recipes/health-page/tests/requests.json +36 -0
  295. package/recipes/health-page/urlcode.yaml +19 -0
  296. package/recipes/json-api/README.md +6 -0
  297. package/recipes/json-api/functions/echo.mjs +3 -0
  298. package/recipes/json-api/recipe.yaml +25 -0
  299. package/recipes/json-api/tests/requests.json +34 -0
  300. package/recipes/json-api/urlcode.yaml +12 -0
  301. package/recipes/middleware/README.md +34 -0
  302. package/recipes/middleware/functions/catalog.mjs +3 -0
  303. package/recipes/middleware/functions/fail.mjs +4 -0
  304. package/recipes/middleware/functions/items.mjs +3 -0
  305. package/recipes/middleware/functions/profile.mjs +3 -0
  306. package/recipes/middleware/functions/resource.mjs +3 -0
  307. package/recipes/middleware/functions/status.mjs +3 -0
  308. package/recipes/middleware/middleware/auth.mjs +48 -0
  309. package/recipes/middleware/middleware/body.mjs +15 -0
  310. package/recipes/middleware/middleware/bucket.mjs +29 -0
  311. package/recipes/middleware/middleware/cors.mjs +21 -0
  312. package/recipes/middleware/middleware/debug.mjs +13 -0
  313. package/recipes/middleware/middleware/envelope.mjs +11 -0
  314. package/recipes/middleware/middleware/errors.mjs +11 -0
  315. package/recipes/middleware/middleware/etag.mjs +18 -0
  316. package/recipes/middleware/middleware/locale.mjs +20 -0
  317. package/recipes/middleware/middleware/maintenance.mjs +10 -0
  318. package/recipes/middleware/middleware/methods.mjs +15 -0
  319. package/recipes/middleware/middleware/negotiate.mjs +20 -0
  320. package/recipes/middleware/middleware/referer.mjs +12 -0
  321. package/recipes/middleware/middleware/request-id.mjs +16 -0
  322. package/recipes/middleware/public/guide.txt +1 -0
  323. package/recipes/middleware/recipe.yaml +50 -0
  324. package/recipes/middleware/tests/requests.json +528 -0
  325. package/recipes/middleware/urlcode.yaml +127 -0
  326. package/recipes/protected-download/README.md +22 -0
  327. package/recipes/protected-download/files/report.txt +1 -0
  328. package/recipes/protected-download/recipe.yaml +31 -0
  329. package/recipes/protected-download/tests/requests.json +32 -0
  330. package/recipes/protected-download/urlcode.yaml +15 -0
  331. package/recipes/redirect/README.md +7 -0
  332. package/recipes/redirect/recipe.yaml +25 -0
  333. package/recipes/redirect/tests/requests.json +19 -0
  334. package/recipes/redirect/urlcode.yaml +9 -0
  335. package/recipes/static-plus-api/README.md +15 -0
  336. package/recipes/static-plus-api/functions/info.mjs +3 -0
  337. package/recipes/static-plus-api/public/assets/index.html +3 -0
  338. package/recipes/static-plus-api/public/assets/site.css +1 -0
  339. package/recipes/static-plus-api/public/index.html +8 -0
  340. package/recipes/static-plus-api/recipe.yaml +29 -0
  341. package/recipes/static-plus-api/tests/requests.json +56 -0
  342. package/recipes/static-plus-api/urlcode.yaml +23 -0
  343. package/recipes/typescript/README.md +8 -0
  344. package/recipes/typescript/functions/hello.ts +5 -0
  345. package/recipes/typescript/recipe.yaml +23 -0
  346. package/recipes/typescript/tests/requests.json +18 -0
  347. package/recipes/typescript/urlcode.yaml +5 -0
  348. package/recipes/webhook-receiver/README.md +20 -0
  349. package/recipes/webhook-receiver/functions/receive.mjs +16 -0
  350. package/recipes/webhook-receiver/recipe.yaml +27 -0
  351. package/recipes/webhook-receiver/tests/requests.json +59 -0
  352. package/recipes/webhook-receiver/urlcode.yaml +23 -0
  353. package/schemas/recipe.schema.json +139 -0
  354. package/schemas/urlcode.schema.json +659 -110
  355. package/skills/urlcode/SKILL.md +119 -0
  356. package/starters/default/.github/workflows/urlcode.yml +23 -0
  357. package/starters/default/.mcp.json +12 -0
  358. package/starters/default/AGENTS.md +79 -0
  359. package/starters/default/urlcode.yaml +0 -1
  360. package/dist/link-api.js +0 -136
  361. package/dist/link-cli.js +0 -141
  362. package/dist/link-events.js +0 -76
  363. package/dist/link-records.js +0 -31
  364. package/dist/link-store-worker.js +0 -150
  365. package/dist/link-store.js +0 -250
  366. package/dist/management-policy.js +0 -41
  367. package/dist/sqlite-version.js +0 -6
  368. package/dist/types/link-api.d.ts +0 -30
  369. package/dist/types/link-cli.d.ts +0 -36
  370. package/dist/types/link-events.d.ts +0 -27
  371. package/dist/types/link-records.d.ts +0 -11
  372. package/dist/types/link-store-worker.d.ts +0 -1
  373. package/dist/types/link-store.d.ts +0 -130
  374. package/dist/types/management-policy.d.ts +0 -9
  375. package/dist/types/sqlite-version.d.ts +0 -1
  376. package/docs/DYNAMIC-LINKS.md +0 -561
  377. package/docs/MANAGEMENT-SECURITY.md +0 -82
  378. package/examples/live-links/README.md +0 -11
  379. package/examples/live-links/tests/requests.json +0 -6
  380. package/examples/live-links/urlcode.yaml +0 -16
@@ -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
  },
@@ -89,6 +84,31 @@
89
84
  "$ref": "#/$defs/policyCache"
90
85
  }
91
86
  ]
87
+ },
88
+ "extensions": {
89
+ "oneOf": [
90
+ {
91
+ "const": false
92
+ },
93
+ {
94
+ "type": "object",
95
+ "maxProperties": 16,
96
+ "propertyNames": {
97
+ "type": "string",
98
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
99
+ },
100
+ "additionalProperties": {
101
+ "oneOf": [
102
+ {
103
+ "const": false
104
+ },
105
+ {
106
+ "type": "object"
107
+ }
108
+ ]
109
+ }
110
+ }
111
+ ]
92
112
  }
93
113
  },
94
114
  "additionalProperties": false
@@ -262,6 +282,31 @@
262
282
  }
263
283
  },
264
284
  "additionalProperties": false
285
+ },
286
+ "extensions": {
287
+ "type": "object",
288
+ "maxProperties": 16,
289
+ "propertyNames": {
290
+ "type": "string",
291
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
292
+ },
293
+ "additionalProperties": {
294
+ "type": "object",
295
+ "properties": {
296
+ "version": {
297
+ "const": "1"
298
+ },
299
+ "config": {
300
+ "type": "object"
301
+ }
302
+ },
303
+ "required": [
304
+ "version",
305
+ "config"
306
+ ],
307
+ "additionalProperties": false
308
+ },
309
+ "description": "Versioned logical extension configurations. Requires explicit external operator registrations pinned to the project revision; never loads project code."
265
310
  }
266
311
  },
267
312
  "required": [
@@ -296,6 +341,16 @@
296
341
  "enabled": {
297
342
  "type": "boolean"
298
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
+ },
299
354
  "expires": {
300
355
  "type": "string"
301
356
  },
@@ -482,85 +537,94 @@
482
537
  "additionalProperties": false
483
538
  },
484
539
  "function": {
485
- "type": "object",
486
- "properties": {
487
- "source": {
540
+ "oneOf": [
541
+ {
488
542
  "type": "string",
543
+ "minLength": 1,
489
544
  "maxLength": 1024
490
545
  },
491
- "export": {
492
- "type": "string",
493
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
494
- },
495
- "args": {
546
+ {
496
547
  "type": "object",
497
- "propertyNames": {
498
- "type": "string",
499
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
500
- },
501
- "additionalProperties": {
502
- "oneOf": [
503
- {
504
- "type": [
505
- "string",
506
- "number",
507
- "boolean"
508
- ]
548
+ "properties": {
549
+ "source": {
550
+ "type": "string",
551
+ "maxLength": 1024
552
+ },
553
+ "export": {
554
+ "type": "string",
555
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
556
+ },
557
+ "args": {
558
+ "type": "object",
559
+ "propertyNames": {
560
+ "type": "string",
561
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
509
562
  },
510
- {
511
- "type": "object",
512
- "properties": {
513
- "from": {
514
- "enum": [
515
- "path",
516
- "query",
517
- "header"
563
+ "additionalProperties": {
564
+ "oneOf": [
565
+ {
566
+ "type": [
567
+ "string",
568
+ "number",
569
+ "boolean"
518
570
  ]
519
571
  },
520
- "name": {
521
- "type": "string"
522
- }
523
- },
524
- "required": [
525
- "from",
526
- "name"
527
- ],
528
- "additionalProperties": false
529
- },
530
- {
531
- "type": "object",
532
- "properties": {
533
- "env": {
534
- "type": "string",
535
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
536
- }
537
- },
538
- "required": [
539
- "env"
540
- ],
541
- "additionalProperties": false
542
- },
543
- {
544
- "type": "object",
545
- "properties": {
546
- "secret": {
547
- "type": "string",
548
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
572
+ {
573
+ "type": "object",
574
+ "properties": {
575
+ "from": {
576
+ "enum": [
577
+ "path",
578
+ "query",
579
+ "header"
580
+ ]
581
+ },
582
+ "name": {
583
+ "type": "string"
584
+ }
585
+ },
586
+ "required": [
587
+ "from",
588
+ "name"
589
+ ],
590
+ "additionalProperties": false
591
+ },
592
+ {
593
+ "type": "object",
594
+ "properties": {
595
+ "env": {
596
+ "type": "string",
597
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
598
+ }
599
+ },
600
+ "required": [
601
+ "env"
602
+ ],
603
+ "additionalProperties": false
604
+ },
605
+ {
606
+ "type": "object",
607
+ "properties": {
608
+ "secret": {
609
+ "type": "string",
610
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
611
+ }
612
+ },
613
+ "required": [
614
+ "secret"
615
+ ],
616
+ "additionalProperties": false
549
617
  }
550
- },
551
- "required": [
552
- "secret"
553
- ],
554
- "additionalProperties": false
618
+ ]
555
619
  }
556
- ]
557
- }
620
+ }
621
+ },
622
+ "required": [
623
+ "source"
624
+ ],
625
+ "additionalProperties": false
558
626
  }
559
- },
560
- "required": [
561
- "source"
562
- ],
563
- "additionalProperties": false
627
+ ]
564
628
  },
565
629
  "env": {
566
630
  "type": "object",
@@ -797,56 +861,87 @@
797
861
  "type": "array",
798
862
  "maxItems": 16,
799
863
  "items": {
800
- "type": "object",
801
- "properties": {
802
- "source": {
864
+ "oneOf": [
865
+ {
803
866
  "type": "string",
867
+ "minLength": 1,
804
868
  "maxLength": 1024
805
869
  },
806
- "export": {
807
- "type": "string",
808
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
870
+ {
871
+ "type": "object",
872
+ "properties": {
873
+ "source": {
874
+ "type": "string",
875
+ "maxLength": 1024
876
+ },
877
+ "export": {
878
+ "type": "string",
879
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
880
+ }
881
+ },
882
+ "required": [
883
+ "source"
884
+ ],
885
+ "additionalProperties": false
809
886
  }
810
- },
811
- "required": [
812
- "source"
813
- ],
814
- "additionalProperties": false
887
+ ]
815
888
  }
816
889
  },
817
- "link": {
890
+ "policies": {
891
+ "$ref": "#/$defs/policies"
892
+ },
893
+ "match": {
894
+ "$ref": "#/$defs/routeMatch"
895
+ },
896
+ "conditional": {
818
897
  "type": "object",
819
898
  "properties": {
820
- "collection": {
821
- "type": "string",
822
- "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
899
+ "cases": {
900
+ "type": "array",
901
+ "minItems": 1,
902
+ "maxItems": 16,
903
+ "items": {
904
+ "$ref": "#/$defs/conditionalCase"
905
+ }
823
906
  },
824
- "code": {
825
- "type": "object",
826
- "properties": {
827
- "from": {
828
- "const": "path"
829
- },
830
- "name": {
831
- "type": "string",
832
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
833
- }
834
- },
835
- "required": [
836
- "from",
837
- "name"
838
- ],
839
- "additionalProperties": false
907
+ "fallback": {
908
+ "$ref": "#/$defs/conditionalReply"
840
909
  }
841
910
  },
842
911
  "required": [
843
- "collection",
844
- "code"
912
+ "cases"
845
913
  ],
846
914
  "additionalProperties": false
847
915
  },
848
- "policies": {
849
- "$ref": "#/$defs/policies"
916
+ "proxy": {
917
+ "$ref": "#/$defs/proxy"
918
+ },
919
+ "signals": {
920
+ "type": "array",
921
+ "minItems": 1,
922
+ "maxItems": 8,
923
+ "items": {
924
+ "$ref": "#/$defs/signal"
925
+ }
926
+ },
927
+ "extension": {
928
+ "type": "string",
929
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
930
+ },
931
+ "auth": {
932
+ "description": "Short form for a route protected by the declared auth extension. true or an object expands to policies.extensions.auth with the same keys minus required; required: false emits no policy. Refused without an extensions.auth declaration or alongside policies.extensions.auth.",
933
+ "oneOf": [
934
+ {
935
+ "const": true
936
+ },
937
+ {
938
+ "$ref": "#/$defs/routeAuth"
939
+ }
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"
850
945
  }
851
946
  },
852
947
  "required": [],
@@ -884,11 +979,58 @@
884
979
  },
885
980
  {
886
981
  "required": [
887
- "link"
982
+ "conditional"
983
+ ]
984
+ },
985
+ {
986
+ "required": [
987
+ "proxy"
988
+ ]
989
+ },
990
+ {
991
+ "required": [
992
+ "extension"
888
993
  ]
889
994
  }
890
995
  ]
891
996
  },
997
+ "routeAuth": {
998
+ "type": "object",
999
+ "description": "Keys other than required mirror the auth extension's policy schema; the installed extension validates the expanded requirement.",
1000
+ "properties": {
1001
+ "required": {
1002
+ "type": "boolean",
1003
+ "default": true
1004
+ },
1005
+ "role": {
1006
+ "type": "string",
1007
+ "minLength": 1,
1008
+ "maxLength": 64
1009
+ },
1010
+ "permission": {
1011
+ "type": "string",
1012
+ "minLength": 1,
1013
+ "maxLength": 128
1014
+ },
1015
+ "verified": {
1016
+ "type": "boolean"
1017
+ },
1018
+ "freshWithinSeconds": {
1019
+ "type": "integer",
1020
+ "minimum": 1,
1021
+ "maximum": 3600
1022
+ },
1023
+ "onDeny": {
1024
+ "enum": [
1025
+ 401,
1026
+ 403,
1027
+ 404,
1028
+ "sign-in"
1029
+ ]
1030
+ }
1031
+ },
1032
+ "additionalProperties": false
1033
+ },
892
1034
  "policyThrottle": {
893
1035
  "type": "object",
894
1036
  "description": "Per-client request budget expressed like the IETF RateLimit-Policy field: quota requests per window seconds. quota and window are required once project and route layers are merged.",
@@ -1222,8 +1364,415 @@
1222
1364
  "$ref": "#/$defs/policyCache"
1223
1365
  }
1224
1366
  ]
1367
+ },
1368
+ "extensions": {
1369
+ "oneOf": [
1370
+ {
1371
+ "const": false
1372
+ },
1373
+ {
1374
+ "type": "object",
1375
+ "maxProperties": 16,
1376
+ "propertyNames": {
1377
+ "type": "string",
1378
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
1379
+ },
1380
+ "additionalProperties": {
1381
+ "oneOf": [
1382
+ {
1383
+ "const": false
1384
+ },
1385
+ {
1386
+ "type": "object"
1387
+ }
1388
+ ]
1389
+ }
1390
+ }
1391
+ ]
1392
+ }
1393
+ },
1394
+ "additionalProperties": false
1395
+ },
1396
+ "routeMatch": {
1397
+ "type": "object",
1398
+ "minProperties": 1,
1399
+ "additionalProperties": false,
1400
+ "properties": {
1401
+ "query": {
1402
+ "type": "object",
1403
+ "minProperties": 1,
1404
+ "maxProperties": 16,
1405
+ "propertyNames": {
1406
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1407
+ },
1408
+ "additionalProperties": {
1409
+ "type": "string",
1410
+ "maxLength": 1024
1411
+ }
1412
+ },
1413
+ "headers": {
1414
+ "type": "object",
1415
+ "minProperties": 1,
1416
+ "maxProperties": 16,
1417
+ "propertyNames": {
1418
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1419
+ },
1420
+ "additionalProperties": {
1421
+ "type": "string",
1422
+ "maxLength": 1024
1423
+ }
1424
+ },
1425
+ "cookies": {
1426
+ "type": "object",
1427
+ "minProperties": 1,
1428
+ "maxProperties": 16,
1429
+ "propertyNames": {
1430
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1431
+ },
1432
+ "additionalProperties": {
1433
+ "type": "string",
1434
+ "maxLength": 1024
1435
+ }
1436
+ },
1437
+ "host": {
1438
+ "type": "string",
1439
+ "maxLength": 255
1440
+ },
1441
+ "method": {
1442
+ "enum": [
1443
+ "GET",
1444
+ "HEAD",
1445
+ "POST",
1446
+ "PUT",
1447
+ "PATCH",
1448
+ "DELETE",
1449
+ "OPTIONS"
1450
+ ]
1451
+ }
1452
+ }
1453
+ },
1454
+ "conditionalReply": {
1455
+ "type": "object",
1456
+ "properties": {
1457
+ "redirect": {
1458
+ "type": "object",
1459
+ "properties": {
1460
+ "url": {
1461
+ "type": "string",
1462
+ "maxLength": 8192
1463
+ },
1464
+ "status": {
1465
+ "enum": [
1466
+ 301,
1467
+ 302,
1468
+ 303,
1469
+ 307,
1470
+ 308
1471
+ ]
1472
+ },
1473
+ "query": {
1474
+ "type": "object",
1475
+ "properties": {
1476
+ "pass": {
1477
+ "oneOf": [
1478
+ {
1479
+ "const": false
1480
+ },
1481
+ {
1482
+ "type": "array",
1483
+ "items": {
1484
+ "type": "string"
1485
+ },
1486
+ "uniqueItems": true
1487
+ }
1488
+ ]
1489
+ },
1490
+ "map": {
1491
+ "type": "object",
1492
+ "additionalProperties": {
1493
+ "type": "object",
1494
+ "properties": {
1495
+ "from": {
1496
+ "enum": [
1497
+ "path",
1498
+ "query",
1499
+ "header"
1500
+ ]
1501
+ },
1502
+ "name": {
1503
+ "type": "string"
1504
+ }
1505
+ },
1506
+ "required": [
1507
+ "from",
1508
+ "name"
1509
+ ],
1510
+ "additionalProperties": false
1511
+ }
1512
+ }
1513
+ },
1514
+ "required": [],
1515
+ "additionalProperties": false
1516
+ }
1517
+ },
1518
+ "required": [
1519
+ "url"
1520
+ ],
1521
+ "additionalProperties": false
1522
+ },
1523
+ "respond": {
1524
+ "type": "object",
1525
+ "properties": {
1526
+ "status": {
1527
+ "type": "integer",
1528
+ "minimum": 200,
1529
+ "maximum": 599
1530
+ },
1531
+ "text": {
1532
+ "type": "string",
1533
+ "maxLength": 1048576
1534
+ },
1535
+ "json": {}
1536
+ },
1537
+ "additionalProperties": false,
1538
+ "not": {
1539
+ "required": [
1540
+ "text",
1541
+ "json"
1542
+ ]
1543
+ }
1544
+ }
1545
+ },
1546
+ "additionalProperties": false,
1547
+ "oneOf": [
1548
+ {
1549
+ "required": [
1550
+ "redirect"
1551
+ ]
1552
+ },
1553
+ {
1554
+ "required": [
1555
+ "respond"
1556
+ ]
1557
+ }
1558
+ ]
1559
+ },
1560
+ "conditionalCase": {
1561
+ "type": "object",
1562
+ "properties": {
1563
+ "redirect": {
1564
+ "type": "object",
1565
+ "properties": {
1566
+ "url": {
1567
+ "type": "string",
1568
+ "maxLength": 8192
1569
+ },
1570
+ "status": {
1571
+ "enum": [
1572
+ 301,
1573
+ 302,
1574
+ 303,
1575
+ 307,
1576
+ 308
1577
+ ]
1578
+ },
1579
+ "query": {
1580
+ "type": "object",
1581
+ "properties": {
1582
+ "pass": {
1583
+ "oneOf": [
1584
+ {
1585
+ "const": false
1586
+ },
1587
+ {
1588
+ "type": "array",
1589
+ "items": {
1590
+ "type": "string"
1591
+ },
1592
+ "uniqueItems": true
1593
+ }
1594
+ ]
1595
+ },
1596
+ "map": {
1597
+ "type": "object",
1598
+ "additionalProperties": {
1599
+ "type": "object",
1600
+ "properties": {
1601
+ "from": {
1602
+ "enum": [
1603
+ "path",
1604
+ "query",
1605
+ "header"
1606
+ ]
1607
+ },
1608
+ "name": {
1609
+ "type": "string"
1610
+ }
1611
+ },
1612
+ "required": [
1613
+ "from",
1614
+ "name"
1615
+ ],
1616
+ "additionalProperties": false
1617
+ }
1618
+ }
1619
+ },
1620
+ "required": [],
1621
+ "additionalProperties": false
1622
+ }
1623
+ },
1624
+ "required": [
1625
+ "url"
1626
+ ],
1627
+ "additionalProperties": false
1628
+ },
1629
+ "respond": {
1630
+ "type": "object",
1631
+ "properties": {
1632
+ "status": {
1633
+ "type": "integer",
1634
+ "minimum": 200,
1635
+ "maximum": 599
1636
+ },
1637
+ "text": {
1638
+ "type": "string",
1639
+ "maxLength": 1048576
1640
+ },
1641
+ "json": {}
1642
+ },
1643
+ "additionalProperties": false,
1644
+ "not": {
1645
+ "required": [
1646
+ "text",
1647
+ "json"
1648
+ ]
1649
+ }
1650
+ },
1651
+ "match": {
1652
+ "$ref": "#/$defs/routeMatch"
1653
+ }
1654
+ },
1655
+ "additionalProperties": false,
1656
+ "oneOf": [
1657
+ {
1658
+ "required": [
1659
+ "redirect"
1660
+ ]
1661
+ },
1662
+ {
1663
+ "required": [
1664
+ "respond"
1665
+ ]
1666
+ }
1667
+ ],
1668
+ "required": [
1669
+ "match"
1670
+ ]
1671
+ },
1672
+ "signal": {
1673
+ "type": "object",
1674
+ "properties": {
1675
+ "url": {
1676
+ "type": "string",
1677
+ "maxLength": 8192
1678
+ },
1679
+ "headers": {
1680
+ "type": "object",
1681
+ "maxProperties": 32,
1682
+ "additionalProperties": {
1683
+ "oneOf": [
1684
+ {
1685
+ "type": "string",
1686
+ "maxLength": 4096
1687
+ },
1688
+ {
1689
+ "type": "object",
1690
+ "properties": {
1691
+ "secret": {
1692
+ "type": "string",
1693
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
1694
+ }
1695
+ },
1696
+ "required": [
1697
+ "secret"
1698
+ ],
1699
+ "additionalProperties": false
1700
+ }
1701
+ ]
1702
+ }
1703
+ }
1704
+ },
1705
+ "required": [
1706
+ "url"
1707
+ ],
1708
+ "additionalProperties": false
1709
+ },
1710
+ "proxy": {
1711
+ "type": "object",
1712
+ "properties": {
1713
+ "url": {
1714
+ "type": "string",
1715
+ "maxLength": 8192
1716
+ },
1717
+ "headers": {
1718
+ "type": "object",
1719
+ "maxProperties": 32,
1720
+ "additionalProperties": {
1721
+ "oneOf": [
1722
+ {
1723
+ "type": "string",
1724
+ "maxLength": 4096
1725
+ },
1726
+ {
1727
+ "type": "object",
1728
+ "properties": {
1729
+ "secret": {
1730
+ "type": "string",
1731
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
1732
+ }
1733
+ },
1734
+ "required": [
1735
+ "secret"
1736
+ ],
1737
+ "additionalProperties": false
1738
+ }
1739
+ ]
1740
+ }
1741
+ },
1742
+ "query": {
1743
+ "type": "array",
1744
+ "maxItems": 32,
1745
+ "uniqueItems": true,
1746
+ "items": {
1747
+ "type": "string",
1748
+ "minLength": 1,
1749
+ "maxLength": 128
1750
+ }
1751
+ },
1752
+ "requestHeaders": {
1753
+ "type": "array",
1754
+ "maxItems": 32,
1755
+ "uniqueItems": true,
1756
+ "items": {
1757
+ "type": "string",
1758
+ "minLength": 1,
1759
+ "maxLength": 128
1760
+ }
1761
+ },
1762
+ "responseHeaders": {
1763
+ "type": "array",
1764
+ "maxItems": 32,
1765
+ "uniqueItems": true,
1766
+ "items": {
1767
+ "type": "string",
1768
+ "minLength": 1,
1769
+ "maxLength": 128
1770
+ }
1225
1771
  }
1226
1772
  },
1773
+ "required": [
1774
+ "url"
1775
+ ],
1227
1776
  "additionalProperties": false
1228
1777
  }
1229
1778
  }