@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.
Files changed (326) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +106 -0
  2. package/.claude/skills/urlcode-operations/SKILL.md +114 -0
  3. package/.claude-plugin/marketplace.json +18 -0
  4. package/CONTRIBUTING.md +30 -2
  5. package/README.md +157 -230
  6. package/ROADMAP.md +85 -2
  7. package/SECURITY.md +8 -1
  8. package/dist/BUILD-MANIFEST.json +62 -32
  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/bulk.js +37 -0
  17. package/dist/capabilities.js +208 -0
  18. package/dist/capability-query.js +72 -0
  19. package/dist/catalog.js +105 -0
  20. package/dist/cli.js +154 -15
  21. package/dist/client-address.js +1 -1
  22. package/dist/compliance-rules/baseline.js +8 -8
  23. package/dist/compliance-rules/privacy.js +3 -3
  24. package/dist/compliance-rules/strict.js +5 -5
  25. package/dist/conditions.js +88 -0
  26. package/dist/config.js +60 -4
  27. package/dist/context.js +156 -0
  28. package/dist/ecosystem-cli.js +88 -0
  29. package/dist/egress.js +98 -0
  30. package/dist/examples.js +92 -0
  31. package/dist/explain-cli.js +64 -0
  32. package/dist/explain.js +132 -0
  33. package/dist/extensions.js +172 -0
  34. package/dist/function-sources.js +15 -3
  35. package/dist/index.js +37 -0
  36. package/dist/init-with.js +165 -0
  37. package/dist/interchange-cli.js +42 -0
  38. package/dist/interchange.js +189 -0
  39. package/dist/link-cli.js +1 -1
  40. package/dist/management-policy.js +0 -1
  41. package/dist/manifest.js +111 -0
  42. package/dist/match.js +2 -2
  43. package/dist/mcp-authoring.js +147 -0
  44. package/dist/mcp.js +97 -0
  45. package/dist/observability.js +6 -0
  46. package/dist/operator-host.js +29 -0
  47. package/dist/plugins.js +12 -0
  48. package/dist/policies/agents.js +2 -2
  49. package/dist/policies/compression.js +2 -1
  50. package/dist/policies/security.js +0 -0
  51. package/dist/policies.js +1 -1
  52. package/dist/policy.js +29 -7
  53. package/dist/prerender.js +100 -41
  54. package/dist/project-tests.js +3 -3
  55. package/dist/provider-verification.js +92 -0
  56. package/dist/proxy.js +44 -0
  57. package/dist/readiness.js +5 -5
  58. package/dist/recipes.js +41 -0
  59. package/dist/route-diff.js +106 -0
  60. package/dist/router.js +42 -2
  61. package/dist/runtime.js +95 -14
  62. package/dist/schema-query.js +62 -0
  63. package/dist/signals.js +24 -0
  64. package/dist/site.js +0 -0
  65. package/dist/tooling.js +96 -0
  66. package/dist/types/adapters.d.ts +7 -4
  67. package/dist/types/agent-lists.d.ts +0 -1
  68. package/dist/types/agents-guide.d.ts +17 -0
  69. package/dist/types/authoring-files.d.ts +10 -0
  70. package/dist/types/aws.d.ts +3 -1
  71. package/dist/types/build-cloudflare.d.ts +1 -0
  72. package/dist/types/bulk.d.ts +27 -0
  73. package/dist/types/capabilities.d.ts +55 -0
  74. package/dist/types/capability-query.d.ts +24 -0
  75. package/dist/types/catalog.d.ts +65 -0
  76. package/dist/types/client-address.d.ts +0 -1
  77. package/dist/types/compliance-rules/baseline.d.ts +1 -9
  78. package/dist/types/compliance-rules/privacy.d.ts +1 -4
  79. package/dist/types/compliance-rules/strict.d.ts +0 -5
  80. package/dist/types/conditions.d.ts +19 -0
  81. package/dist/types/config.d.ts +20 -2
  82. package/dist/types/context.d.ts +65 -0
  83. package/dist/types/ecosystem-cli.d.ts +17 -0
  84. package/dist/types/egress.d.ts +46 -0
  85. package/dist/types/examples.d.ts +50 -0
  86. package/dist/types/explain-cli.d.ts +11 -0
  87. package/dist/types/explain.d.ts +95 -0
  88. package/dist/types/extensions.d.ts +122 -0
  89. package/dist/types/function-sources.d.ts +5 -0
  90. package/dist/types/index.d.ts +33 -0
  91. package/dist/types/init-with.d.ts +30 -0
  92. package/dist/types/interchange-cli.d.ts +16 -0
  93. package/dist/types/interchange.d.ts +42 -0
  94. package/dist/types/link-cli.d.ts +2 -1
  95. package/dist/types/management-policy.d.ts +0 -1
  96. package/dist/types/manifest.d.ts +81 -0
  97. package/dist/types/match.d.ts +1 -0
  98. package/dist/types/mcp-authoring.d.ts +92 -0
  99. package/dist/types/mcp.d.ts +12 -0
  100. package/dist/types/observability.d.ts +2 -0
  101. package/dist/types/operator-host.d.ts +8 -0
  102. package/dist/types/plugins.d.ts +2 -0
  103. package/dist/types/policies/agents.d.ts +0 -2
  104. package/dist/types/policies/compression.d.ts +2 -0
  105. package/dist/types/policies/security.d.ts +0 -1
  106. package/dist/types/policy.d.ts +15 -4
  107. package/dist/types/project-tests.d.ts +3 -1
  108. package/dist/types/provider-verification.d.ts +53 -0
  109. package/dist/types/proxy.d.ts +21 -0
  110. package/dist/types/readiness.d.ts +1 -1
  111. package/dist/types/recipes.d.ts +30 -0
  112. package/dist/types/route-diff.d.ts +27 -0
  113. package/dist/types/runtime.d.ts +11 -0
  114. package/dist/types/schema-query.d.ts +12 -0
  115. package/dist/types/signals.d.ts +25 -0
  116. package/dist/types/site.d.ts +0 -1
  117. package/dist/types/tooling.d.ts +115 -0
  118. package/dist/types/types.d.ts +57 -0
  119. package/dist/types/typescript-authoring.d.ts +12 -0
  120. package/dist/types/vercel.d.ts +3 -1
  121. package/dist/types/verify-deployment.d.ts +47 -0
  122. package/dist/types.js +21 -2
  123. package/dist/typescript-authoring.js +104 -0
  124. package/dist/vercel.js +4 -3
  125. package/dist/verify-deployment.js +270 -0
  126. package/docs/AI-AUTHORING.md +130 -8
  127. package/docs/BULK.md +79 -0
  128. package/docs/CAPABILITIES.md +179 -0
  129. package/docs/CAPACITY.md +1 -1
  130. package/docs/CI.md +142 -0
  131. package/docs/CONDITIONS.md +74 -0
  132. package/docs/DEPLOYMENT-CHECKS.md +108 -0
  133. package/docs/DYNAMIC-LINKS.md +18 -518
  134. package/docs/EGRESS.md +125 -0
  135. package/docs/EXTENSIONS.md +226 -0
  136. package/docs/FRAMEWORK.md +182 -0
  137. package/docs/INSTALL.md +45 -7
  138. package/docs/INTERCHANGE.md +134 -0
  139. package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
  140. package/docs/MIDDLEWARE.md +2 -0
  141. package/docs/NEXT-PHASE-PLAN.md +90 -0
  142. package/docs/NEXT-STEPS.md +415 -0
  143. package/docs/OBSERVABILITY.md +4 -2
  144. package/docs/OPERATIONAL-PROOF.md +4 -1
  145. package/docs/OPERATIONS.md +6 -3
  146. package/docs/PLUGINS.md +37 -0
  147. package/docs/POLICIES.md +12 -309
  148. package/docs/PRERENDER.md +40 -0
  149. package/docs/PROJECT-DIRECTION.md +42 -0
  150. package/docs/PROVIDER-VERIFICATION.md +84 -0
  151. package/docs/READINESS.md +21 -1
  152. package/docs/README.md +82 -31
  153. package/docs/RECIPES.md +99 -0
  154. package/docs/RELEASE-READINESS.md +11 -9
  155. package/docs/RELEASE-SECURITY.md +27 -4
  156. package/docs/SECURITY-AUDIT.md +1 -1
  157. package/docs/SPECIFICATION.md +95 -8
  158. package/docs/SPIKE-BUSINESS-SUITE.md +1013 -0
  159. package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
  160. package/docs/SPIKE-EXTENSIONS.md +1 -0
  161. package/docs/SPIKE-LAMBDA-COMPILE.md +199 -0
  162. package/docs/STANDARDS.md +150 -142
  163. package/docs/STARTERS.md +21 -1
  164. package/docs/TOOLING.md +291 -0
  165. package/docs/TYPESCRIPT-AUTHORING.md +67 -0
  166. package/docs/TYPESCRIPT.md +1 -1
  167. package/docs/USABILITY-REVIEW.md +123 -0
  168. package/docs/YAML-GUIDE.md +18 -479
  169. package/docs/YAML-REFERENCE.md +127 -16
  170. package/docs/links/cli.md +110 -0
  171. package/docs/links/limits.md +175 -0
  172. package/docs/links/management-api.md +80 -0
  173. package/docs/links/pools.md +75 -0
  174. package/docs/links/setup.md +135 -0
  175. package/docs/policies/agents.md +1 -1
  176. package/docs/policies/contract.md +52 -0
  177. package/docs/policies/hardened.md +56 -0
  178. package/docs/policies/interoperability.md +169 -0
  179. package/docs/policies/operations.md +45 -0
  180. package/docs/yaml/assets.md +36 -0
  181. package/docs/yaml/conditions.md +20 -0
  182. package/docs/yaml/functions.md +160 -0
  183. package/docs/yaml/links.md +30 -0
  184. package/docs/yaml/middleware.md +29 -0
  185. package/docs/yaml/organization.md +74 -0
  186. package/docs/yaml/policies.md +37 -0
  187. package/docs/yaml/redirects.md +64 -0
  188. package/docs/yaml/responses.md +57 -0
  189. package/docs/yaml/site.md +24 -0
  190. package/examples/assets/example.yaml +17 -0
  191. package/examples/aws/example.yaml +20 -0
  192. package/examples/cloudflare/example.yaml +19 -0
  193. package/examples/compliance/example.yaml +11 -0
  194. package/examples/conditions/README.md +12 -0
  195. package/examples/conditions/example.yaml +19 -0
  196. package/examples/conditions/tests/requests.json +13 -0
  197. package/examples/conditions/urlcode.yaml +24 -0
  198. package/examples/cookbook/README.md +8 -4
  199. package/examples/cookbook/example.yaml +17 -0
  200. package/examples/cookbook/functions/catalog.mjs +3 -0
  201. package/examples/cookbook/functions/fail.mjs +4 -0
  202. package/examples/cookbook/functions/items.mjs +3 -0
  203. package/examples/cookbook/functions/profile.mjs +3 -0
  204. package/examples/cookbook/functions/resource.mjs +3 -0
  205. package/examples/cookbook/functions/status.mjs +3 -0
  206. package/examples/cookbook/middleware/auth.mjs +48 -0
  207. package/examples/cookbook/middleware/body.mjs +15 -0
  208. package/examples/cookbook/middleware/bucket.mjs +19 -0
  209. package/examples/cookbook/middleware/cors.mjs +21 -0
  210. package/examples/cookbook/middleware/debug.mjs +13 -0
  211. package/examples/cookbook/middleware/envelope.mjs +11 -0
  212. package/examples/cookbook/middleware/errors.mjs +11 -0
  213. package/examples/cookbook/middleware/etag.mjs +18 -0
  214. package/examples/cookbook/middleware/locale.mjs +16 -0
  215. package/examples/cookbook/middleware/maintenance.mjs +10 -0
  216. package/examples/cookbook/middleware/methods.mjs +15 -0
  217. package/examples/cookbook/middleware/negotiate.mjs +20 -0
  218. package/examples/cookbook/middleware/referer.mjs +12 -0
  219. package/examples/cookbook/middleware/request-id.mjs +16 -0
  220. package/examples/cookbook/route-index.json +676 -0
  221. package/examples/cookbook/routes/middleware.yaml +126 -0
  222. package/examples/cookbook/tests/requests.json +526 -0
  223. package/examples/cookbook/urlcode.yaml +1 -0
  224. package/examples/egress/README.md +22 -0
  225. package/examples/egress/example.yaml +19 -0
  226. package/examples/egress/urlcode.yaml +19 -0
  227. package/examples/extensions/README.md +7 -0
  228. package/examples/extensions/example.yaml +21 -0
  229. package/examples/extensions/urlcode.yaml +25 -0
  230. package/examples/live-links/example.yaml +21 -0
  231. package/examples/monitoring/example.yaml +8 -0
  232. package/examples/prerender/example.yaml +16 -0
  233. package/examples/provider-conformance/README.md +12 -0
  234. package/examples/provider-conformance/example.yaml +14 -0
  235. package/examples/provider-conformance/urlcode.yaml +34 -0
  236. package/examples/tunnel/example.yaml +8 -0
  237. package/examples/vercel/example.yaml +19 -0
  238. package/llms-full.txt +2709 -0
  239. package/llms.txt +48 -19
  240. package/package.json +29 -7
  241. package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
  242. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +106 -0
  243. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +114 -0
  244. package/recipes/authenticated-json-api/README.md +51 -0
  245. package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
  246. package/recipes/authenticated-json-api/recipe.yaml +34 -0
  247. package/recipes/authenticated-json-api/tests/requests.json +39 -0
  248. package/recipes/authenticated-json-api/urlcode.yaml +12 -0
  249. package/recipes/contact-form/README.md +25 -0
  250. package/recipes/contact-form/functions/contact.mjs +17 -0
  251. package/recipes/contact-form/recipe.yaml +33 -0
  252. package/recipes/contact-form/tests/requests.json +47 -0
  253. package/recipes/contact-form/urlcode.yaml +18 -0
  254. package/recipes/cors-api/README.md +16 -0
  255. package/recipes/cors-api/functions/items.mjs +3 -0
  256. package/recipes/cors-api/middleware/cors.mjs +21 -0
  257. package/recipes/cors-api/recipe.yaml +26 -0
  258. package/recipes/cors-api/tests/requests.json +65 -0
  259. package/recipes/cors-api/urlcode.yaml +12 -0
  260. package/recipes/health-page/README.md +13 -0
  261. package/recipes/health-page/recipe.yaml +23 -0
  262. package/recipes/health-page/tests/requests.json +36 -0
  263. package/recipes/health-page/urlcode.yaml +19 -0
  264. package/recipes/json-api/README.md +6 -0
  265. package/recipes/json-api/functions/echo.mjs +3 -0
  266. package/recipes/json-api/recipe.yaml +25 -0
  267. package/recipes/json-api/tests/requests.json +34 -0
  268. package/recipes/json-api/urlcode.yaml +12 -0
  269. package/recipes/middleware/README.md +34 -0
  270. package/recipes/middleware/functions/catalog.mjs +3 -0
  271. package/recipes/middleware/functions/fail.mjs +4 -0
  272. package/recipes/middleware/functions/items.mjs +3 -0
  273. package/recipes/middleware/functions/profile.mjs +3 -0
  274. package/recipes/middleware/functions/resource.mjs +3 -0
  275. package/recipes/middleware/functions/status.mjs +3 -0
  276. package/recipes/middleware/middleware/auth.mjs +48 -0
  277. package/recipes/middleware/middleware/body.mjs +15 -0
  278. package/recipes/middleware/middleware/bucket.mjs +19 -0
  279. package/recipes/middleware/middleware/cors.mjs +21 -0
  280. package/recipes/middleware/middleware/debug.mjs +13 -0
  281. package/recipes/middleware/middleware/envelope.mjs +11 -0
  282. package/recipes/middleware/middleware/errors.mjs +11 -0
  283. package/recipes/middleware/middleware/etag.mjs +18 -0
  284. package/recipes/middleware/middleware/locale.mjs +16 -0
  285. package/recipes/middleware/middleware/maintenance.mjs +10 -0
  286. package/recipes/middleware/middleware/methods.mjs +15 -0
  287. package/recipes/middleware/middleware/negotiate.mjs +20 -0
  288. package/recipes/middleware/middleware/referer.mjs +12 -0
  289. package/recipes/middleware/middleware/request-id.mjs +16 -0
  290. package/recipes/middleware/public/guide.txt +1 -0
  291. package/recipes/middleware/recipe.yaml +50 -0
  292. package/recipes/middleware/tests/requests.json +528 -0
  293. package/recipes/middleware/urlcode.yaml +127 -0
  294. package/recipes/protected-download/README.md +22 -0
  295. package/recipes/protected-download/files/report.txt +1 -0
  296. package/recipes/protected-download/recipe.yaml +31 -0
  297. package/recipes/protected-download/tests/requests.json +32 -0
  298. package/recipes/protected-download/urlcode.yaml +15 -0
  299. package/recipes/redirect/README.md +7 -0
  300. package/recipes/redirect/recipe.yaml +25 -0
  301. package/recipes/redirect/tests/requests.json +19 -0
  302. package/recipes/redirect/urlcode.yaml +9 -0
  303. package/recipes/static-plus-api/README.md +15 -0
  304. package/recipes/static-plus-api/functions/info.mjs +3 -0
  305. package/recipes/static-plus-api/public/assets/index.html +3 -0
  306. package/recipes/static-plus-api/public/assets/site.css +1 -0
  307. package/recipes/static-plus-api/public/index.html +8 -0
  308. package/recipes/static-plus-api/recipe.yaml +29 -0
  309. package/recipes/static-plus-api/tests/requests.json +56 -0
  310. package/recipes/static-plus-api/urlcode.yaml +23 -0
  311. package/recipes/typescript/README.md +7 -0
  312. package/recipes/typescript/functions/hello.ts +5 -0
  313. package/recipes/typescript/recipe.yaml +23 -0
  314. package/recipes/typescript/tests/requests.json +18 -0
  315. package/recipes/typescript/urlcode.yaml +5 -0
  316. package/recipes/webhook-receiver/README.md +16 -0
  317. package/recipes/webhook-receiver/functions/receive.mjs +16 -0
  318. package/recipes/webhook-receiver/recipe.yaml +26 -0
  319. package/recipes/webhook-receiver/tests/requests.json +59 -0
  320. package/recipes/webhook-receiver/urlcode.yaml +16 -0
  321. package/schemas/recipe.schema.json +138 -0
  322. package/schemas/urlcode.schema.json +656 -80
  323. package/skills/urlcode/SKILL.md +98 -0
  324. package/starters/default/.github/workflows/urlcode.yml +23 -0
  325. package/starters/default/.mcp.json +12 -0
  326. package/starters/default/AGENTS.md +79 -0
@@ -89,6 +89,31 @@
89
89
  "$ref": "#/$defs/policyCache"
90
90
  }
91
91
  ]
92
+ },
93
+ "extensions": {
94
+ "oneOf": [
95
+ {
96
+ "const": false
97
+ },
98
+ {
99
+ "type": "object",
100
+ "maxProperties": 16,
101
+ "propertyNames": {
102
+ "type": "string",
103
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
104
+ },
105
+ "additionalProperties": {
106
+ "oneOf": [
107
+ {
108
+ "const": false
109
+ },
110
+ {
111
+ "type": "object"
112
+ }
113
+ ]
114
+ }
115
+ }
116
+ ]
92
117
  }
93
118
  },
94
119
  "additionalProperties": false
@@ -262,6 +287,31 @@
262
287
  }
263
288
  },
264
289
  "additionalProperties": false
290
+ },
291
+ "extensions": {
292
+ "type": "object",
293
+ "maxProperties": 16,
294
+ "propertyNames": {
295
+ "type": "string",
296
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
297
+ },
298
+ "additionalProperties": {
299
+ "type": "object",
300
+ "properties": {
301
+ "version": {
302
+ "const": "1"
303
+ },
304
+ "config": {
305
+ "type": "object"
306
+ }
307
+ },
308
+ "required": [
309
+ "version",
310
+ "config"
311
+ ],
312
+ "additionalProperties": false
313
+ },
314
+ "description": "Versioned logical extension configurations. Requires explicit external operator registrations pinned to the project revision; never loads project code."
265
315
  }
266
316
  },
267
317
  "required": [
@@ -482,85 +532,94 @@
482
532
  "additionalProperties": false
483
533
  },
484
534
  "function": {
485
- "type": "object",
486
- "properties": {
487
- "source": {
535
+ "oneOf": [
536
+ {
488
537
  "type": "string",
538
+ "minLength": 1,
489
539
  "maxLength": 1024
490
540
  },
491
- "export": {
492
- "type": "string",
493
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
494
- },
495
- "args": {
541
+ {
496
542
  "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
- ]
543
+ "properties": {
544
+ "source": {
545
+ "type": "string",
546
+ "maxLength": 1024
547
+ },
548
+ "export": {
549
+ "type": "string",
550
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
551
+ },
552
+ "args": {
553
+ "type": "object",
554
+ "propertyNames": {
555
+ "type": "string",
556
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
509
557
  },
510
- {
511
- "type": "object",
512
- "properties": {
513
- "from": {
514
- "enum": [
515
- "path",
516
- "query",
517
- "header"
558
+ "additionalProperties": {
559
+ "oneOf": [
560
+ {
561
+ "type": [
562
+ "string",
563
+ "number",
564
+ "boolean"
518
565
  ]
519
566
  },
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_]*$"
567
+ {
568
+ "type": "object",
569
+ "properties": {
570
+ "from": {
571
+ "enum": [
572
+ "path",
573
+ "query",
574
+ "header"
575
+ ]
576
+ },
577
+ "name": {
578
+ "type": "string"
579
+ }
580
+ },
581
+ "required": [
582
+ "from",
583
+ "name"
584
+ ],
585
+ "additionalProperties": false
586
+ },
587
+ {
588
+ "type": "object",
589
+ "properties": {
590
+ "env": {
591
+ "type": "string",
592
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
593
+ }
594
+ },
595
+ "required": [
596
+ "env"
597
+ ],
598
+ "additionalProperties": false
599
+ },
600
+ {
601
+ "type": "object",
602
+ "properties": {
603
+ "secret": {
604
+ "type": "string",
605
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
606
+ }
607
+ },
608
+ "required": [
609
+ "secret"
610
+ ],
611
+ "additionalProperties": false
549
612
  }
550
- },
551
- "required": [
552
- "secret"
553
- ],
554
- "additionalProperties": false
613
+ ]
555
614
  }
556
- ]
557
- }
615
+ }
616
+ },
617
+ "required": [
618
+ "source"
619
+ ],
620
+ "additionalProperties": false
558
621
  }
559
- },
560
- "required": [
561
- "source"
562
- ],
563
- "additionalProperties": false
622
+ ]
564
623
  },
565
624
  "env": {
566
625
  "type": "object",
@@ -797,21 +856,30 @@
797
856
  "type": "array",
798
857
  "maxItems": 16,
799
858
  "items": {
800
- "type": "object",
801
- "properties": {
802
- "source": {
859
+ "oneOf": [
860
+ {
803
861
  "type": "string",
862
+ "minLength": 1,
804
863
  "maxLength": 1024
805
864
  },
806
- "export": {
807
- "type": "string",
808
- "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
865
+ {
866
+ "type": "object",
867
+ "properties": {
868
+ "source": {
869
+ "type": "string",
870
+ "maxLength": 1024
871
+ },
872
+ "export": {
873
+ "type": "string",
874
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
875
+ }
876
+ },
877
+ "required": [
878
+ "source"
879
+ ],
880
+ "additionalProperties": false
809
881
  }
810
- },
811
- "required": [
812
- "source"
813
- ],
814
- "additionalProperties": false
882
+ ]
815
883
  }
816
884
  },
817
885
  "link": {
@@ -847,6 +915,55 @@
847
915
  },
848
916
  "policies": {
849
917
  "$ref": "#/$defs/policies"
918
+ },
919
+ "match": {
920
+ "$ref": "#/$defs/routeMatch"
921
+ },
922
+ "conditional": {
923
+ "type": "object",
924
+ "properties": {
925
+ "cases": {
926
+ "type": "array",
927
+ "minItems": 1,
928
+ "maxItems": 16,
929
+ "items": {
930
+ "$ref": "#/$defs/conditionalCase"
931
+ }
932
+ },
933
+ "fallback": {
934
+ "$ref": "#/$defs/conditionalReply"
935
+ }
936
+ },
937
+ "required": [
938
+ "cases"
939
+ ],
940
+ "additionalProperties": false
941
+ },
942
+ "proxy": {
943
+ "$ref": "#/$defs/proxy"
944
+ },
945
+ "signals": {
946
+ "type": "array",
947
+ "minItems": 1,
948
+ "maxItems": 8,
949
+ "items": {
950
+ "$ref": "#/$defs/signal"
951
+ }
952
+ },
953
+ "extension": {
954
+ "type": "string",
955
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
956
+ },
957
+ "auth": {
958
+ "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.",
959
+ "oneOf": [
960
+ {
961
+ "const": true
962
+ },
963
+ {
964
+ "$ref": "#/$defs/routeAuth"
965
+ }
966
+ ]
850
967
  }
851
968
  },
852
969
  "required": [],
@@ -886,9 +1003,61 @@
886
1003
  "required": [
887
1004
  "link"
888
1005
  ]
1006
+ },
1007
+ {
1008
+ "required": [
1009
+ "conditional"
1010
+ ]
1011
+ },
1012
+ {
1013
+ "required": [
1014
+ "proxy"
1015
+ ]
1016
+ },
1017
+ {
1018
+ "required": [
1019
+ "extension"
1020
+ ]
889
1021
  }
890
1022
  ]
891
1023
  },
1024
+ "routeAuth": {
1025
+ "type": "object",
1026
+ "description": "Keys other than required mirror the auth extension's policy schema; the installed extension validates the expanded requirement.",
1027
+ "properties": {
1028
+ "required": {
1029
+ "type": "boolean",
1030
+ "default": true
1031
+ },
1032
+ "role": {
1033
+ "type": "string",
1034
+ "minLength": 1,
1035
+ "maxLength": 64
1036
+ },
1037
+ "permission": {
1038
+ "type": "string",
1039
+ "minLength": 1,
1040
+ "maxLength": 128
1041
+ },
1042
+ "verified": {
1043
+ "type": "boolean"
1044
+ },
1045
+ "freshWithinSeconds": {
1046
+ "type": "integer",
1047
+ "minimum": 1,
1048
+ "maximum": 3600
1049
+ },
1050
+ "onDeny": {
1051
+ "enum": [
1052
+ 401,
1053
+ 403,
1054
+ 404,
1055
+ "sign-in"
1056
+ ]
1057
+ }
1058
+ },
1059
+ "additionalProperties": false
1060
+ },
892
1061
  "policyThrottle": {
893
1062
  "type": "object",
894
1063
  "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 +1391,415 @@
1222
1391
  "$ref": "#/$defs/policyCache"
1223
1392
  }
1224
1393
  ]
1394
+ },
1395
+ "extensions": {
1396
+ "oneOf": [
1397
+ {
1398
+ "const": false
1399
+ },
1400
+ {
1401
+ "type": "object",
1402
+ "maxProperties": 16,
1403
+ "propertyNames": {
1404
+ "type": "string",
1405
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
1406
+ },
1407
+ "additionalProperties": {
1408
+ "oneOf": [
1409
+ {
1410
+ "const": false
1411
+ },
1412
+ {
1413
+ "type": "object"
1414
+ }
1415
+ ]
1416
+ }
1417
+ }
1418
+ ]
1419
+ }
1420
+ },
1421
+ "additionalProperties": false
1422
+ },
1423
+ "routeMatch": {
1424
+ "type": "object",
1425
+ "minProperties": 1,
1426
+ "additionalProperties": false,
1427
+ "properties": {
1428
+ "query": {
1429
+ "type": "object",
1430
+ "minProperties": 1,
1431
+ "maxProperties": 16,
1432
+ "propertyNames": {
1433
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1434
+ },
1435
+ "additionalProperties": {
1436
+ "type": "string",
1437
+ "maxLength": 1024
1438
+ }
1439
+ },
1440
+ "headers": {
1441
+ "type": "object",
1442
+ "minProperties": 1,
1443
+ "maxProperties": 16,
1444
+ "propertyNames": {
1445
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1446
+ },
1447
+ "additionalProperties": {
1448
+ "type": "string",
1449
+ "maxLength": 1024
1450
+ }
1451
+ },
1452
+ "cookies": {
1453
+ "type": "object",
1454
+ "minProperties": 1,
1455
+ "maxProperties": 16,
1456
+ "propertyNames": {
1457
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$"
1458
+ },
1459
+ "additionalProperties": {
1460
+ "type": "string",
1461
+ "maxLength": 1024
1462
+ }
1463
+ },
1464
+ "host": {
1465
+ "type": "string",
1466
+ "maxLength": 255
1467
+ },
1468
+ "method": {
1469
+ "enum": [
1470
+ "GET",
1471
+ "HEAD",
1472
+ "POST",
1473
+ "PUT",
1474
+ "PATCH",
1475
+ "DELETE",
1476
+ "OPTIONS"
1477
+ ]
1478
+ }
1479
+ }
1480
+ },
1481
+ "conditionalReply": {
1482
+ "type": "object",
1483
+ "properties": {
1484
+ "redirect": {
1485
+ "type": "object",
1486
+ "properties": {
1487
+ "url": {
1488
+ "type": "string",
1489
+ "maxLength": 8192
1490
+ },
1491
+ "status": {
1492
+ "enum": [
1493
+ 301,
1494
+ 302,
1495
+ 303,
1496
+ 307,
1497
+ 308
1498
+ ]
1499
+ },
1500
+ "query": {
1501
+ "type": "object",
1502
+ "properties": {
1503
+ "pass": {
1504
+ "oneOf": [
1505
+ {
1506
+ "const": false
1507
+ },
1508
+ {
1509
+ "type": "array",
1510
+ "items": {
1511
+ "type": "string"
1512
+ },
1513
+ "uniqueItems": true
1514
+ }
1515
+ ]
1516
+ },
1517
+ "map": {
1518
+ "type": "object",
1519
+ "additionalProperties": {
1520
+ "type": "object",
1521
+ "properties": {
1522
+ "from": {
1523
+ "enum": [
1524
+ "path",
1525
+ "query",
1526
+ "header"
1527
+ ]
1528
+ },
1529
+ "name": {
1530
+ "type": "string"
1531
+ }
1532
+ },
1533
+ "required": [
1534
+ "from",
1535
+ "name"
1536
+ ],
1537
+ "additionalProperties": false
1538
+ }
1539
+ }
1540
+ },
1541
+ "required": [],
1542
+ "additionalProperties": false
1543
+ }
1544
+ },
1545
+ "required": [
1546
+ "url"
1547
+ ],
1548
+ "additionalProperties": false
1549
+ },
1550
+ "respond": {
1551
+ "type": "object",
1552
+ "properties": {
1553
+ "status": {
1554
+ "type": "integer",
1555
+ "minimum": 200,
1556
+ "maximum": 599
1557
+ },
1558
+ "text": {
1559
+ "type": "string",
1560
+ "maxLength": 1048576
1561
+ },
1562
+ "json": {}
1563
+ },
1564
+ "additionalProperties": false,
1565
+ "not": {
1566
+ "required": [
1567
+ "text",
1568
+ "json"
1569
+ ]
1570
+ }
1571
+ }
1572
+ },
1573
+ "additionalProperties": false,
1574
+ "oneOf": [
1575
+ {
1576
+ "required": [
1577
+ "redirect"
1578
+ ]
1579
+ },
1580
+ {
1581
+ "required": [
1582
+ "respond"
1583
+ ]
1584
+ }
1585
+ ]
1586
+ },
1587
+ "conditionalCase": {
1588
+ "type": "object",
1589
+ "properties": {
1590
+ "redirect": {
1591
+ "type": "object",
1592
+ "properties": {
1593
+ "url": {
1594
+ "type": "string",
1595
+ "maxLength": 8192
1596
+ },
1597
+ "status": {
1598
+ "enum": [
1599
+ 301,
1600
+ 302,
1601
+ 303,
1602
+ 307,
1603
+ 308
1604
+ ]
1605
+ },
1606
+ "query": {
1607
+ "type": "object",
1608
+ "properties": {
1609
+ "pass": {
1610
+ "oneOf": [
1611
+ {
1612
+ "const": false
1613
+ },
1614
+ {
1615
+ "type": "array",
1616
+ "items": {
1617
+ "type": "string"
1618
+ },
1619
+ "uniqueItems": true
1620
+ }
1621
+ ]
1622
+ },
1623
+ "map": {
1624
+ "type": "object",
1625
+ "additionalProperties": {
1626
+ "type": "object",
1627
+ "properties": {
1628
+ "from": {
1629
+ "enum": [
1630
+ "path",
1631
+ "query",
1632
+ "header"
1633
+ ]
1634
+ },
1635
+ "name": {
1636
+ "type": "string"
1637
+ }
1638
+ },
1639
+ "required": [
1640
+ "from",
1641
+ "name"
1642
+ ],
1643
+ "additionalProperties": false
1644
+ }
1645
+ }
1646
+ },
1647
+ "required": [],
1648
+ "additionalProperties": false
1649
+ }
1650
+ },
1651
+ "required": [
1652
+ "url"
1653
+ ],
1654
+ "additionalProperties": false
1655
+ },
1656
+ "respond": {
1657
+ "type": "object",
1658
+ "properties": {
1659
+ "status": {
1660
+ "type": "integer",
1661
+ "minimum": 200,
1662
+ "maximum": 599
1663
+ },
1664
+ "text": {
1665
+ "type": "string",
1666
+ "maxLength": 1048576
1667
+ },
1668
+ "json": {}
1669
+ },
1670
+ "additionalProperties": false,
1671
+ "not": {
1672
+ "required": [
1673
+ "text",
1674
+ "json"
1675
+ ]
1676
+ }
1677
+ },
1678
+ "match": {
1679
+ "$ref": "#/$defs/routeMatch"
1680
+ }
1681
+ },
1682
+ "additionalProperties": false,
1683
+ "oneOf": [
1684
+ {
1685
+ "required": [
1686
+ "redirect"
1687
+ ]
1688
+ },
1689
+ {
1690
+ "required": [
1691
+ "respond"
1692
+ ]
1693
+ }
1694
+ ],
1695
+ "required": [
1696
+ "match"
1697
+ ]
1698
+ },
1699
+ "signal": {
1700
+ "type": "object",
1701
+ "properties": {
1702
+ "url": {
1703
+ "type": "string",
1704
+ "maxLength": 8192
1705
+ },
1706
+ "headers": {
1707
+ "type": "object",
1708
+ "maxProperties": 32,
1709
+ "additionalProperties": {
1710
+ "oneOf": [
1711
+ {
1712
+ "type": "string",
1713
+ "maxLength": 4096
1714
+ },
1715
+ {
1716
+ "type": "object",
1717
+ "properties": {
1718
+ "secret": {
1719
+ "type": "string",
1720
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
1721
+ }
1722
+ },
1723
+ "required": [
1724
+ "secret"
1725
+ ],
1726
+ "additionalProperties": false
1727
+ }
1728
+ ]
1729
+ }
1730
+ }
1731
+ },
1732
+ "required": [
1733
+ "url"
1734
+ ],
1735
+ "additionalProperties": false
1736
+ },
1737
+ "proxy": {
1738
+ "type": "object",
1739
+ "properties": {
1740
+ "url": {
1741
+ "type": "string",
1742
+ "maxLength": 8192
1743
+ },
1744
+ "headers": {
1745
+ "type": "object",
1746
+ "maxProperties": 32,
1747
+ "additionalProperties": {
1748
+ "oneOf": [
1749
+ {
1750
+ "type": "string",
1751
+ "maxLength": 4096
1752
+ },
1753
+ {
1754
+ "type": "object",
1755
+ "properties": {
1756
+ "secret": {
1757
+ "type": "string",
1758
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
1759
+ }
1760
+ },
1761
+ "required": [
1762
+ "secret"
1763
+ ],
1764
+ "additionalProperties": false
1765
+ }
1766
+ ]
1767
+ }
1768
+ },
1769
+ "query": {
1770
+ "type": "array",
1771
+ "maxItems": 32,
1772
+ "uniqueItems": true,
1773
+ "items": {
1774
+ "type": "string",
1775
+ "minLength": 1,
1776
+ "maxLength": 128
1777
+ }
1778
+ },
1779
+ "requestHeaders": {
1780
+ "type": "array",
1781
+ "maxItems": 32,
1782
+ "uniqueItems": true,
1783
+ "items": {
1784
+ "type": "string",
1785
+ "minLength": 1,
1786
+ "maxLength": 128
1787
+ }
1788
+ },
1789
+ "responseHeaders": {
1790
+ "type": "array",
1791
+ "maxItems": 32,
1792
+ "uniqueItems": true,
1793
+ "items": {
1794
+ "type": "string",
1795
+ "minLength": 1,
1796
+ "maxLength": 128
1797
+ }
1225
1798
  }
1226
1799
  },
1800
+ "required": [
1801
+ "url"
1802
+ ],
1227
1803
  "additionalProperties": false
1228
1804
  }
1229
1805
  }