@jimhoyd/urlcode 0.4.2 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/urlcode-authoring/SKILL.md +57 -14
- package/.claude/skills/urlcode-operations/SKILL.md +4 -0
- package/README.md +42 -18
- package/SECURITY.md +5 -3
- package/dist/BUILD-MANIFEST.json +30 -27
- package/dist/agent-context.js +82 -0
- package/dist/agents-guide.js +42 -42
- package/dist/authoring.js +12 -2
- package/dist/body-schema.js +159 -0
- package/dist/build-cloudflare.js +2 -0
- package/dist/capabilities.js +1 -1
- package/dist/cli.js +28 -12
- package/dist/config.js +74 -6
- package/dist/context.js +4 -6
- package/dist/errors.js +3 -1
- package/dist/examples.js +1 -1
- package/dist/extensions.js +60 -2
- package/dist/http-policy.js +19 -4
- package/dist/http-response.js +2 -2
- package/dist/init-with.js +71 -9
- package/dist/mcp.js +15 -2
- package/dist/pattern-guard.js +32 -0
- package/dist/policies/security.js +0 -0
- package/dist/project-tests.js +35 -11
- package/dist/readiness.js +184 -32
- package/dist/recipes.js +1 -1
- package/dist/router.js +17 -0
- package/dist/runtime.js +26 -3
- package/dist/scaffold.js +0 -0
- package/dist/server.js +26 -3
- package/dist/site.js +0 -0
- package/dist/tooling.js +2 -1
- package/dist/types/agent-context.d.ts +44 -0
- package/dist/types/authoring.d.ts +3 -1
- package/dist/types/body-schema.d.ts +58 -0
- package/dist/types/config.d.ts +10 -2
- package/dist/types/context.d.ts +1 -1
- package/dist/types/errors.d.ts +9 -1
- package/dist/types/examples.d.ts +1 -1
- package/dist/types/extensions.d.ts +47 -2
- package/dist/types/http-policy.d.ts +3 -0
- package/dist/types/init-with.d.ts +10 -1
- package/dist/types/pattern-guard.d.ts +10 -0
- package/dist/types/project-tests.d.ts +9 -0
- package/dist/types/readiness.d.ts +68 -0
- package/dist/types/recipes.d.ts +1 -1
- package/dist/types/runtime.d.ts +4 -0
- package/dist/types/server.d.ts +9 -1
- package/dist/types/tooling.d.ts +1 -0
- package/dist/types/types.d.ts +13 -0
- package/dist/types.js +10 -2
- package/dist/typescript-authoring.js +5 -3
- package/dist/verify-deployment.js +16 -10
- package/examples/body-validation/README.md +16 -0
- package/examples/body-validation/example.yaml +17 -0
- package/examples/body-validation/tests/requests.json +15 -0
- package/examples/body-validation/urlcode.yaml +34 -0
- package/examples/coverage-waiver/README.md +8 -0
- package/examples/coverage-waiver/example.yaml +16 -0
- package/examples/coverage-waiver/functions/notes.mjs +2 -0
- package/examples/coverage-waiver/tests/requests.json +3 -0
- package/examples/coverage-waiver/urlcode.yaml +10 -0
- package/examples/data-dir/README.md +39 -0
- package/examples/data-dir/data/welcome.txt +1 -0
- package/examples/data-dir/example.yaml +22 -0
- package/examples/data-dir/functions/note.mjs +18 -0
- package/examples/data-dir/tests/requests.json +6 -0
- package/examples/data-dir/urlcode.yaml +6 -0
- package/examples/lifecycle/README.md +15 -0
- package/examples/lifecycle/example.yaml +19 -0
- package/examples/lifecycle/functions/notes.mjs +29 -0
- package/examples/lifecycle/tests/requests.json +12 -0
- package/examples/lifecycle/urlcode.yaml +29 -0
- package/examples/not-found/README.md +10 -0
- package/examples/not-found/example.yaml +17 -0
- package/examples/not-found/public/404.html +3 -0
- package/examples/not-found/public/index.html +3 -0
- package/examples/not-found/tests/requests.json +7 -0
- package/examples/not-found/urlcode.yaml +7 -0
- package/examples/shared-blocks/README.md +11 -0
- package/examples/shared-blocks/example.yaml +17 -0
- package/examples/shared-blocks/tests/requests.json +7 -0
- package/examples/shared-blocks/urlcode.yaml +37 -0
- package/llms-full.txt +364 -49
- package/llms.txt +44 -6
- package/package.json +15 -26
- package/recipes/static-page/README.md +9 -0
- package/recipes/static-page/public/index.html +11 -0
- package/recipes/static-page/recipe.yaml +21 -0
- package/recipes/static-page/tests/requests.json +22 -0
- package/recipes/static-page/urlcode.yaml +7 -0
- package/recipes/static-plus-api/README.md +6 -0
- package/recipes/static-plus-api/urlcode.yaml +4 -0
- package/recipes/store-crud/README.md +53 -0
- package/recipes/store-crud/recipe.yaml +31 -0
- package/recipes/store-crud/tests/requests.json +18 -0
- package/recipes/store-crud/urlcode.yaml +18 -0
- package/schemas/urlcode.schema.json +125 -60
- package/skills/urlcode/SKILL.md +47 -27
- package/starters/default/AGENTS.md +43 -43
- package/starters/page/README.md +14 -0
- package/starters/page/public/index.html +12 -0
- package/starters/page/tests/requests.json +17 -0
- package/starters/page/urlcode.yaml +6 -0
- package/.claude-plugin/marketplace.json +0 -18
- package/CONTRIBUTING.md +0 -148
- package/ROADMAP.md +0 -70
- package/docs/AI-AUTHORING.md +0 -339
- package/docs/ASSETS.md +0 -107
- package/docs/AUTH-BACKUP.md +0 -32
- package/docs/AWS.md +0 -86
- package/docs/BEST-PRACTICES.md +0 -276
- package/docs/BULK.md +0 -79
- package/docs/CAPABILITIES.md +0 -192
- package/docs/CAPACITY.md +0 -305
- package/docs/CI-FOLLOWUP-2026-09-19.md +0 -97
- package/docs/CI-RELEASE-AUDIT-2026-09-19.md +0 -322
- package/docs/CI.md +0 -147
- package/docs/CLOUDFLARE.md +0 -109
- package/docs/CODEBASE-AUDIT-2026-09-20.md +0 -284
- package/docs/COMPLIANCE.md +0 -239
- package/docs/COMPOSING-A-SITE.md +0 -287
- package/docs/CONDITIONS.md +0 -74
- package/docs/CONTAINER-PROMOTION.md +0 -74
- package/docs/DEPLOYMENT-CHECKS.md +0 -108
- package/docs/DEVELOPMENT-PIPELINE.md +0 -304
- package/docs/EGRESS.md +0 -125
- package/docs/EXTENSIONS.md +0 -403
- package/docs/FRAMEWORK.md +0 -217
- package/docs/FUNCTION-SECURITY.md +0 -251
- package/docs/HTTP.md +0 -129
- package/docs/INSTALL.md +0 -128
- package/docs/INTERCHANGE.md +0 -134
- package/docs/LOAD-TESTING.md +0 -91
- package/docs/LOCAL-DEVELOPMENT.md +0 -102
- package/docs/MIDDLEWARE-EXAMPLES.md +0 -75
- package/docs/MIDDLEWARE.md +0 -102
- package/docs/MONITORING.md +0 -115
- package/docs/OBSERVABILITY.md +0 -222
- package/docs/OPEN-DECISIONS.md +0 -149
- package/docs/OPERATIONAL-PROOF.md +0 -41
- package/docs/OPERATIONS.md +0 -201
- package/docs/ORGANIZATION.md +0 -135
- package/docs/PERFORMANCE.md +0 -72
- package/docs/PLUGINS.md +0 -271
- package/docs/POLICIES.md +0 -211
- package/docs/PRERENDER.md +0 -245
- package/docs/PROJECT-DIRECTION.md +0 -118
- package/docs/PROVIDER-VERIFICATION.md +0 -84
- package/docs/READINESS.md +0 -153
- package/docs/README.md +0 -93
- package/docs/RECIPES.md +0 -99
- package/docs/RELEASE-0.4.0-alpha.3.md +0 -50
- package/docs/RELEASE-0.4.1.md +0 -73
- package/docs/RELEASE-0.4.2.md +0 -30
- package/docs/RELEASE-READINESS.md +0 -146
- package/docs/RELEASE-SECURITY.md +0 -100
- package/docs/RESILIENCE.md +0 -161
- package/docs/ROUTING.md +0 -92
- package/docs/SANDBOX-REVIEW.md +0 -72
- package/docs/SCAFFOLDING.md +0 -70
- package/docs/SECURITY-AUDIT.md +0 -164
- package/docs/SITE.md +0 -150
- package/docs/SPECIFICATION.md +0 -359
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +0 -288
- package/docs/SPIKE-BUSINESS-SUITE.md +0 -1029
- package/docs/SPIKE-CORE-LAYERING.md +0 -368
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +0 -207
- package/docs/STANDARDS.md +0 -311
- package/docs/STARTERS.md +0 -83
- package/docs/STATIC.md +0 -105
- package/docs/TOOLING.md +0 -298
- package/docs/TUNNELS.md +0 -72
- package/docs/TYPESCRIPT-AUTHORING.md +0 -87
- package/docs/TYPESCRIPT.md +0 -123
- package/docs/VERCEL.md +0 -114
- package/docs/VERSION-ALIGNMENT.md +0 -88
- package/docs/YAML-GUIDE.md +0 -57
- package/docs/YAML-REFERENCE.md +0 -449
- package/docs/archive/2026-09-19/EXTENSION-IMPLEMENTATION.md +0 -68
- package/docs/archive/2026-09-19/MANAGEMENT-SECURITY.md +0 -102
- package/docs/archive/2026-09-19/NEXT-PHASE-PLAN.md +0 -108
- package/docs/archive/2026-09-19/NEXT-STEPS.md +0 -646
- package/docs/archive/2026-09-19/OPEN-DECISIONS.md +0 -277
- package/docs/archive/2026-09-19/RELEASE-SECURITY.md +0 -186
- package/docs/archive/2026-09-19/ROADMAP.md +0 -387
- package/docs/archive/2026-09-19/SPIKE-EXTENSION-MODEL.md +0 -430
- package/docs/archive/2026-09-19/SPIKE-EXTENSIONS.md +0 -492
- package/docs/archive/2026-09-19/SPIKE-LAMBDA-COMPILE.md +0 -365
- package/docs/archive/2026-09-19/SPIKE-MONOREPO.md +0 -778
- package/docs/archive/2026-09-19/USABILITY-REVIEW.md +0 -139
- package/docs/archive/2026-09-20/OPEN-DECISIONS-COMPLETED.md +0 -116
- package/docs/archive/README.md +0 -29
- package/docs/policies/agents.md +0 -182
- package/docs/policies/cache.md +0 -152
- package/docs/policies/compression.md +0 -169
- package/docs/policies/contract.md +0 -52
- package/docs/policies/hardened.md +0 -56
- package/docs/policies/interoperability.md +0 -169
- package/docs/policies/operations.md +0 -45
- package/docs/policies/security.md +0 -161
- package/docs/policies/throttle.md +0 -103
- package/docs/yaml/assets.md +0 -36
- package/docs/yaml/conditions.md +0 -20
- package/docs/yaml/functions.md +0 -168
- package/docs/yaml/middleware.md +0 -31
- package/docs/yaml/organization.md +0 -74
- package/docs/yaml/policies.md +0 -37
- package/docs/yaml/redirects.md +0 -64
- package/docs/yaml/responses.md +0 -57
- package/docs/yaml/site.md +0 -24
- package/packaging/claude-plugin/.claude-plugin/plugin.json +0 -19
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +0 -130
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +0 -108
package/docs/YAML-REFERENCE.md
DELETED
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
# YAML field reference
|
|
2
|
-
|
|
3
|
-
Generated from the bundled JSON Schema by `npm run docs:reference`. Required
|
|
4
|
-
means required within its containing object, not that the object itself must be
|
|
5
|
-
present. `routes.*` means a route path; other `*` markers mean user-selected
|
|
6
|
-
keys. `[]` means an array item. Option rows describe union alternatives.
|
|
7
|
-
|
|
8
|
-
Read the [YAML guide](YAML-GUIDE.md) for examples and [specification](SPECIFICATION.md)
|
|
9
|
-
for semantic validation beyond JSON Schema. Exactly one handler is required per
|
|
10
|
-
route; respond.text/respond.json are mutually exclusive. Runtime defaults include
|
|
11
|
-
GET/HEAD, redirect 302, respond 200, default module export, and asset no-cache.
|
|
12
|
-
Only Set-Cookie accepts response header arrays. This table does not imply all
|
|
13
|
-
schema-valid combinations activate successfully.
|
|
14
|
-
|
|
15
|
-
| Field | Type | Required | Schema constraints |
|
|
16
|
-
|---|---|---|---|
|
|
17
|
-
| `version` | constant | yes | const: "1" |
|
|
18
|
-
| `routes` | object | yes | maxProperties: 100000 |
|
|
19
|
-
| `routes.*` | object | no | unknown keys rejected |
|
|
20
|
-
| `routes.*.methods` | array | no | default: ["GET","HEAD"]; minItems: 1; uniqueItems: true |
|
|
21
|
-
| `routes.*.methods[]` | string | no | enum: ["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"] |
|
|
22
|
-
| `routes.*.enabled` | boolean | no | — |
|
|
23
|
-
| `routes.*.sandbox` | boolean | no | default: false |
|
|
24
|
-
| `routes.*.sandboxReason` | string | no | maxLength: 500 |
|
|
25
|
-
| `routes.*.expires` | string | no | — |
|
|
26
|
-
| `routes.*.description` | string | no | maxLength: 1024 |
|
|
27
|
-
| `routes.*.parameters` | array | no | maxItems: 64 |
|
|
28
|
-
| `routes.*.parameters[]` | object | no | unknown keys rejected |
|
|
29
|
-
| `routes.*.parameters[].name` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_-]*$" |
|
|
30
|
-
| `routes.*.parameters[].in` | string | yes | enum: ["path","query","header"] |
|
|
31
|
-
| `routes.*.parameters[].required` | boolean | no | — |
|
|
32
|
-
| `routes.*.parameters[].schema` | object | yes | unknown keys rejected |
|
|
33
|
-
| `routes.*.parameters[].schema.type` | string | yes | enum: ["string","integer","number","boolean","array"] |
|
|
34
|
-
| `routes.*.parameters[].schema.enum` | array | no | minItems: 1; uniqueItems: true |
|
|
35
|
-
| `routes.*.parameters[].schema.enum[]` | string / number / boolean | no | — |
|
|
36
|
-
| `routes.*.parameters[].schema.default` | string / number / boolean / array | no | — |
|
|
37
|
-
| `routes.*.parameters[].schema.default[]` | string / number / boolean | no | — |
|
|
38
|
-
| `routes.*.parameters[].schema.minLength` | integer | no | minimum: 0; maximum: 8192 |
|
|
39
|
-
| `routes.*.parameters[].schema.maxLength` | integer | no | minimum: 0; maximum: 8192 |
|
|
40
|
-
| `routes.*.parameters[].schema.minimum` | number | no | — |
|
|
41
|
-
| `routes.*.parameters[].schema.maximum` | number | no | — |
|
|
42
|
-
| `routes.*.parameters[].schema.items` | object | no | unknown keys rejected |
|
|
43
|
-
| `routes.*.parameters[].schema.items.type` | string | yes | enum: ["string","integer","number","boolean"] |
|
|
44
|
-
| `routes.*.parameters[].schema.maxItems` | integer | no | minimum: 0; maximum: 100 |
|
|
45
|
-
| `routes.*.redirect` | object | no | unknown keys rejected |
|
|
46
|
-
| `routes.*.redirect.url` | string | yes | maxLength: 8192 |
|
|
47
|
-
| `routes.*.redirect.status` | number | no | enum: [301,302,303,307,308] |
|
|
48
|
-
| `routes.*.redirect.query` | object | no | unknown keys rejected |
|
|
49
|
-
| `routes.*.redirect.query.pass` | one of the shapes below | no | — |
|
|
50
|
-
| `routes.*.redirect.query.pass (option 1)` | constant | no | const: false |
|
|
51
|
-
| `routes.*.redirect.query.pass (option 2)` | array | no | uniqueItems: true |
|
|
52
|
-
| `routes.*.redirect.query.pass (option 2)[]` | string | no | — |
|
|
53
|
-
| `routes.*.redirect.query.map` | object | no | — |
|
|
54
|
-
| `routes.*.redirect.query.map.*` | object | no | unknown keys rejected |
|
|
55
|
-
| `routes.*.redirect.query.map.*.from` | string | yes | enum: ["path","query","header"] |
|
|
56
|
-
| `routes.*.redirect.query.map.*.name` | string | yes | — |
|
|
57
|
-
| `routes.*.function` | one of the shapes below | no | — |
|
|
58
|
-
| `routes.*.function (option 1)` | string | no | minLength: 1; maxLength: 1024 |
|
|
59
|
-
| `routes.*.function (option 2)` | object | no | unknown keys rejected |
|
|
60
|
-
| `routes.*.function (option 2).source` | string | yes | maxLength: 1024 |
|
|
61
|
-
| `routes.*.function (option 2).export` | string | no | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
62
|
-
| `routes.*.function (option 2).args` | object | no | — |
|
|
63
|
-
| `routes.*.function (option 2).args.*` | one of the shapes below | no | — |
|
|
64
|
-
| `routes.*.function (option 2).args.* (option 1)` | string / number / boolean | no | — |
|
|
65
|
-
| `routes.*.function (option 2).args.* (option 2)` | object | no | unknown keys rejected |
|
|
66
|
-
| `routes.*.function (option 2).args.* (option 2).from` | string | yes | enum: ["path","query","header"] |
|
|
67
|
-
| `routes.*.function (option 2).args.* (option 2).name` | string | yes | — |
|
|
68
|
-
| `routes.*.function (option 2).args.* (option 3)` | object | no | unknown keys rejected |
|
|
69
|
-
| `routes.*.function (option 2).args.* (option 3).env` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
70
|
-
| `routes.*.function (option 2).args.* (option 4)` | object | no | unknown keys rejected |
|
|
71
|
-
| `routes.*.function (option 2).args.* (option 4).secret` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
72
|
-
| `routes.*.env` | object | no | — |
|
|
73
|
-
| `routes.*.env.*` | one of the shapes below | no | — |
|
|
74
|
-
| `routes.*.env.* (option 1)` | object | no | unknown keys rejected |
|
|
75
|
-
| `routes.*.env.* (option 1).value` | string | yes | — |
|
|
76
|
-
| `routes.*.env.* (option 2)` | object | no | unknown keys rejected |
|
|
77
|
-
| `routes.*.env.* (option 2).env` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
78
|
-
| `routes.*.secrets` | object | no | — |
|
|
79
|
-
| `routes.*.secrets.*` | object | no | unknown keys rejected |
|
|
80
|
-
| `routes.*.secrets.*.secret` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
81
|
-
| `routes.*.page` | object | no | unknown keys rejected |
|
|
82
|
-
| `routes.*.page.file` | string | yes | minLength: 1; maxLength: 1024 |
|
|
83
|
-
| `routes.*.page.contentType` | string | no | maxLength: 128; pattern: "^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$" |
|
|
84
|
-
| `routes.*.page.cacheControl` | string | no | enum: ["no-cache","no-store","public, max-age=3600","public, max-age=31536000, immutable"] |
|
|
85
|
-
| `routes.*.download` | object | no | unknown keys rejected |
|
|
86
|
-
| `routes.*.download.file` | string | yes | minLength: 1; maxLength: 1024 |
|
|
87
|
-
| `routes.*.download.contentType` | string | no | maxLength: 128; pattern: "^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$" |
|
|
88
|
-
| `routes.*.download.cacheControl` | string | no | enum: ["no-cache","no-store","public, max-age=3600","public, max-age=31536000, immutable"] |
|
|
89
|
-
| `routes.*.download.filename` | string | no | minLength: 1; maxLength: 255 |
|
|
90
|
-
| `routes.*.static` | object | no | unknown keys rejected |
|
|
91
|
-
| `routes.*.static.directory` | string | yes | minLength: 1; maxLength: 1024 |
|
|
92
|
-
| `routes.*.static.contentType` | string | no | maxLength: 128; pattern: "^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$" |
|
|
93
|
-
| `routes.*.static.cacheControl` | string | no | enum: ["no-cache","no-store","public, max-age=3600","public, max-age=31536000, immutable"] |
|
|
94
|
-
| `routes.*.static.index` | string | no | pattern: "^[A-Za-z0-9_-]+\\.html$" |
|
|
95
|
-
| `routes.*.request` | object | no | unknown keys rejected |
|
|
96
|
-
| `routes.*.request.body` | object | no | unknown keys rejected |
|
|
97
|
-
| `routes.*.request.body.required` | boolean | no | — |
|
|
98
|
-
| `routes.*.request.body.maxBytes` | integer | no | minimum: 0; maximum: 1048576 |
|
|
99
|
-
| `routes.*.request.body.contentTypes` | array | no | minItems: 1; maxItems: 16; uniqueItems: true |
|
|
100
|
-
| `routes.*.request.body.contentTypes[]` | string | no | pattern: "^[a-z0-9!#$&^_.+-]+/[a-z0-9!#$&^_.+-]+$" |
|
|
101
|
-
| `routes.*.request.body.format` | string | no | enum: ["text","json"] |
|
|
102
|
-
| `routes.*.response` | object | no | unknown keys rejected |
|
|
103
|
-
| `routes.*.response.headers` | object | no | maxProperties: 64 |
|
|
104
|
-
| `routes.*.response.headers.*` | one of the shapes below | no | — |
|
|
105
|
-
| `routes.*.response.headers.* (option 1)` | string | no | maxLength: 4096 |
|
|
106
|
-
| `routes.*.response.headers.* (option 2)` | array | no | minItems: 1; maxItems: 16 |
|
|
107
|
-
| `routes.*.response.headers.* (option 2)[]` | string | no | maxLength: 4096 |
|
|
108
|
-
| `routes.*.respond` | object | no | unknown keys rejected |
|
|
109
|
-
| `routes.*.respond.status` | integer | no | minimum: 200; maximum: 599 |
|
|
110
|
-
| `routes.*.respond.text` | string | no | maxLength: 1048576 |
|
|
111
|
-
| `routes.*.respond.json` | any JSON value | no | — |
|
|
112
|
-
| `routes.*.middleware` | array | no | maxItems: 16 |
|
|
113
|
-
| `routes.*.middleware[]` | one of the shapes below | no | — |
|
|
114
|
-
| `routes.*.middleware[] (option 1)` | string | no | minLength: 1; maxLength: 1024 |
|
|
115
|
-
| `routes.*.middleware[] (option 2)` | object | no | unknown keys rejected |
|
|
116
|
-
| `routes.*.middleware[] (option 2).source` | string | yes | maxLength: 1024 |
|
|
117
|
-
| `routes.*.middleware[] (option 2).export` | string | no | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
118
|
-
| `routes.*.policies` | object | no | unknown keys rejected |
|
|
119
|
-
| `routes.*.policies.profile` | string | no | pattern: "^[a-z][a-z0-9-]{0,63}$" |
|
|
120
|
-
| `routes.*.policies.throttle` | one of the shapes below | no | — |
|
|
121
|
-
| `routes.*.policies.throttle (option 1)` | constant | no | const: false |
|
|
122
|
-
| `routes.*.policies.throttle (option 2)` | object | no | unknown keys rejected |
|
|
123
|
-
| `routes.*.policies.throttle (option 2).quota` | integer | no | minimum: 1; maximum: 1000000 |
|
|
124
|
-
| `routes.*.policies.throttle (option 2).window` | integer | no | minimum: 1; maximum: 86400 |
|
|
125
|
-
| `routes.*.policies.throttle (option 2).partition` | string | no | enum: ["client","route","client-route"]; default: "client" |
|
|
126
|
-
| `routes.*.policies.throttle (option 2).status` | integer | no | default: 429; minimum: 400; maximum: 599 |
|
|
127
|
-
| `routes.*.policies.throttle (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
128
|
-
| `routes.*.policies.throttle (option 2).maxKeys` | integer | no | default: 100000; minimum: 1000; maximum: 10000000 |
|
|
129
|
-
| `routes.*.policies.agents` | one of the shapes below | no | — |
|
|
130
|
-
| `routes.*.policies.agents (option 1)` | constant | no | const: false |
|
|
131
|
-
| `routes.*.policies.agents (option 2)` | object | no | unknown keys rejected |
|
|
132
|
-
| `routes.*.policies.agents (option 2).deny` | array | no | maxItems: 32; uniqueItems: true |
|
|
133
|
-
| `routes.*.policies.agents (option 2).deny[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
134
|
-
| `routes.*.policies.agents (option 2).allow` | array | no | maxItems: 32; uniqueItems: true |
|
|
135
|
-
| `routes.*.policies.agents (option 2).allow[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
136
|
-
| `routes.*.policies.agents (option 2).denyPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
137
|
-
| `routes.*.policies.agents (option 2).denyPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
138
|
-
| `routes.*.policies.agents (option 2).allowPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
139
|
-
| `routes.*.policies.agents (option 2).allowPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
140
|
-
| `routes.*.policies.agents (option 2).denyEmpty` | boolean | no | default: false |
|
|
141
|
-
| `routes.*.policies.agents (option 2).status` | integer | no | default: 403; minimum: 400; maximum: 599 |
|
|
142
|
-
| `routes.*.policies.agents (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
143
|
-
| `routes.*.policies.security` | one of the shapes below | no | — |
|
|
144
|
-
| `routes.*.policies.security (option 1)` | constant | no | const: false |
|
|
145
|
-
| `routes.*.policies.security (option 2)` | object | no | unknown keys rejected |
|
|
146
|
-
| `routes.*.policies.security (option 2).headers` | string | no | enum: ["oshp","oshp-no-csp","off"]; default: "oshp" |
|
|
147
|
-
| `routes.*.policies.security (option 2).set` | object | no | maxProperties: 32 |
|
|
148
|
-
| `routes.*.policies.security (option 2).set.*` | string | no | maxLength: 4096 |
|
|
149
|
-
| `routes.*.policies.security (option 2).unset` | array | no | maxItems: 32; uniqueItems: true |
|
|
150
|
-
| `routes.*.policies.security (option 2).unset[]` | string | no | minLength: 1; maxLength: 128 |
|
|
151
|
-
| `routes.*.policies.compression` | one of the shapes below | no | — |
|
|
152
|
-
| `routes.*.policies.compression (option 1)` | constant | no | const: false |
|
|
153
|
-
| `routes.*.policies.compression (option 2)` | object | no | unknown keys rejected |
|
|
154
|
-
| `routes.*.policies.compression (option 2).encodings` | array | no | default: ["br","gzip"]; minItems: 1; uniqueItems: true |
|
|
155
|
-
| `routes.*.policies.compression (option 2).encodings[]` | string | no | enum: ["br","gzip","deflate","zstd"] |
|
|
156
|
-
| `routes.*.policies.compression (option 2).minBytes` | integer | no | default: 1024; minimum: 0; maximum: 1048576 |
|
|
157
|
-
| `routes.*.policies.compression (option 2).types` | array | no | maxItems: 64; uniqueItems: true |
|
|
158
|
-
| `routes.*.policies.compression (option 2).types[]` | string | no | minLength: 1; maxLength: 128 |
|
|
159
|
-
| `routes.*.policies.compression (option 2).level` | integer | no | minimum: 1; maximum: 11 |
|
|
160
|
-
| `routes.*.policies.compression (option 2).allowWithSecrets` | boolean | no | default: false |
|
|
161
|
-
| `routes.*.policies.cache` | one of the shapes below | no | — |
|
|
162
|
-
| `routes.*.policies.cache (option 1)` | constant | no | const: false |
|
|
163
|
-
| `routes.*.policies.cache (option 2)` | object | no | unknown keys rejected |
|
|
164
|
-
| `routes.*.policies.cache (option 2).strategy` | string | no | enum: ["no-store","revalidate","public","immutable","swr","sie","micro","cdn-only","private"] |
|
|
165
|
-
| `routes.*.policies.cache (option 2).maxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
166
|
-
| `routes.*.policies.cache (option 2).staleWhileRevalidate` | integer | no | minimum: 0; maximum: 31536000 |
|
|
167
|
-
| `routes.*.policies.cache (option 2).staleIfError` | integer | no | minimum: 0; maximum: 31536000 |
|
|
168
|
-
| `routes.*.policies.cache (option 2).cdnMaxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
169
|
-
| `routes.*.policies.cache (option 2).originTtl` | integer | no | minimum: 0; maximum: 86400 |
|
|
170
|
-
| `routes.*.policies.cache (option 2).vary` | array | no | maxItems: 8; uniqueItems: true |
|
|
171
|
-
| `routes.*.policies.cache (option 2).vary[]` | string | no | minLength: 1; maxLength: 128 |
|
|
172
|
-
| `routes.*.policies.cache (option 2).statuses` | array | no | maxItems: 16; uniqueItems: true |
|
|
173
|
-
| `routes.*.policies.cache (option 2).statuses[]` | integer | no | minimum: 200; maximum: 599 |
|
|
174
|
-
| `routes.*.policies.cache (option 2).maxBytes` | integer | no | minimum: 0; maximum: 16777216 |
|
|
175
|
-
| `routes.*.policies.cache (option 2).maxEntries` | integer | no | minimum: 1; maximum: 1000000 |
|
|
176
|
-
| `routes.*.policies.cache (option 2).force` | boolean | no | default: false |
|
|
177
|
-
| `routes.*.policies.extensions` | one of the shapes below | no | — |
|
|
178
|
-
| `routes.*.policies.extensions (option 1)` | constant | no | const: false |
|
|
179
|
-
| `routes.*.policies.extensions (option 2)` | object | no | maxProperties: 16 |
|
|
180
|
-
| `routes.*.policies.extensions (option 2).*` | one of the shapes below | no | — |
|
|
181
|
-
| `routes.*.policies.extensions (option 2).* (option 1)` | constant | no | const: false |
|
|
182
|
-
| `routes.*.policies.extensions (option 2).* (option 2)` | object | no | — |
|
|
183
|
-
| `routes.*.match` | object | no | minProperties: 1; unknown keys rejected |
|
|
184
|
-
| `routes.*.match.query` | object | no | minProperties: 1; maxProperties: 16 |
|
|
185
|
-
| `routes.*.match.query.*` | string | no | maxLength: 1024 |
|
|
186
|
-
| `routes.*.match.headers` | object | no | minProperties: 1; maxProperties: 16 |
|
|
187
|
-
| `routes.*.match.headers.*` | string | no | maxLength: 1024 |
|
|
188
|
-
| `routes.*.match.cookies` | object | no | minProperties: 1; maxProperties: 16 |
|
|
189
|
-
| `routes.*.match.cookies.*` | string | no | maxLength: 1024 |
|
|
190
|
-
| `routes.*.match.host` | string | no | maxLength: 255 |
|
|
191
|
-
| `routes.*.match.method` | string | no | enum: ["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"] |
|
|
192
|
-
| `routes.*.conditional` | object | no | unknown keys rejected |
|
|
193
|
-
| `routes.*.conditional.cases` | array | yes | minItems: 1; maxItems: 16 |
|
|
194
|
-
| `routes.*.conditional.cases[]` | object | no | unknown keys rejected |
|
|
195
|
-
| `routes.*.conditional.cases[].redirect` | object | no | unknown keys rejected |
|
|
196
|
-
| `routes.*.conditional.cases[].redirect.url` | string | yes | maxLength: 8192 |
|
|
197
|
-
| `routes.*.conditional.cases[].redirect.status` | number | no | enum: [301,302,303,307,308] |
|
|
198
|
-
| `routes.*.conditional.cases[].redirect.query` | object | no | unknown keys rejected |
|
|
199
|
-
| `routes.*.conditional.cases[].redirect.query.pass` | one of the shapes below | no | — |
|
|
200
|
-
| `routes.*.conditional.cases[].redirect.query.pass (option 1)` | constant | no | const: false |
|
|
201
|
-
| `routes.*.conditional.cases[].redirect.query.pass (option 2)` | array | no | uniqueItems: true |
|
|
202
|
-
| `routes.*.conditional.cases[].redirect.query.pass (option 2)[]` | string | no | — |
|
|
203
|
-
| `routes.*.conditional.cases[].redirect.query.map` | object | no | — |
|
|
204
|
-
| `routes.*.conditional.cases[].redirect.query.map.*` | object | no | unknown keys rejected |
|
|
205
|
-
| `routes.*.conditional.cases[].redirect.query.map.*.from` | string | yes | enum: ["path","query","header"] |
|
|
206
|
-
| `routes.*.conditional.cases[].redirect.query.map.*.name` | string | yes | — |
|
|
207
|
-
| `routes.*.conditional.cases[].respond` | object | no | unknown keys rejected |
|
|
208
|
-
| `routes.*.conditional.cases[].respond.status` | integer | no | minimum: 200; maximum: 599 |
|
|
209
|
-
| `routes.*.conditional.cases[].respond.text` | string | no | maxLength: 1048576 |
|
|
210
|
-
| `routes.*.conditional.cases[].respond.json` | any JSON value | no | — |
|
|
211
|
-
| `routes.*.conditional.cases[].match` | object | yes | minProperties: 1; unknown keys rejected |
|
|
212
|
-
| `routes.*.conditional.cases[].match.query` | object | no | minProperties: 1; maxProperties: 16 |
|
|
213
|
-
| `routes.*.conditional.cases[].match.query.*` | string | no | maxLength: 1024 |
|
|
214
|
-
| `routes.*.conditional.cases[].match.headers` | object | no | minProperties: 1; maxProperties: 16 |
|
|
215
|
-
| `routes.*.conditional.cases[].match.headers.*` | string | no | maxLength: 1024 |
|
|
216
|
-
| `routes.*.conditional.cases[].match.cookies` | object | no | minProperties: 1; maxProperties: 16 |
|
|
217
|
-
| `routes.*.conditional.cases[].match.cookies.*` | string | no | maxLength: 1024 |
|
|
218
|
-
| `routes.*.conditional.cases[].match.host` | string | no | maxLength: 255 |
|
|
219
|
-
| `routes.*.conditional.cases[].match.method` | string | no | enum: ["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"] |
|
|
220
|
-
| `routes.*.conditional.fallback` | object | no | unknown keys rejected |
|
|
221
|
-
| `routes.*.conditional.fallback.redirect` | object | no | unknown keys rejected |
|
|
222
|
-
| `routes.*.conditional.fallback.redirect.url` | string | yes | maxLength: 8192 |
|
|
223
|
-
| `routes.*.conditional.fallback.redirect.status` | number | no | enum: [301,302,303,307,308] |
|
|
224
|
-
| `routes.*.conditional.fallback.redirect.query` | object | no | unknown keys rejected |
|
|
225
|
-
| `routes.*.conditional.fallback.redirect.query.pass` | one of the shapes below | no | — |
|
|
226
|
-
| `routes.*.conditional.fallback.redirect.query.pass (option 1)` | constant | no | const: false |
|
|
227
|
-
| `routes.*.conditional.fallback.redirect.query.pass (option 2)` | array | no | uniqueItems: true |
|
|
228
|
-
| `routes.*.conditional.fallback.redirect.query.pass (option 2)[]` | string | no | — |
|
|
229
|
-
| `routes.*.conditional.fallback.redirect.query.map` | object | no | — |
|
|
230
|
-
| `routes.*.conditional.fallback.redirect.query.map.*` | object | no | unknown keys rejected |
|
|
231
|
-
| `routes.*.conditional.fallback.redirect.query.map.*.from` | string | yes | enum: ["path","query","header"] |
|
|
232
|
-
| `routes.*.conditional.fallback.redirect.query.map.*.name` | string | yes | — |
|
|
233
|
-
| `routes.*.conditional.fallback.respond` | object | no | unknown keys rejected |
|
|
234
|
-
| `routes.*.conditional.fallback.respond.status` | integer | no | minimum: 200; maximum: 599 |
|
|
235
|
-
| `routes.*.conditional.fallback.respond.text` | string | no | maxLength: 1048576 |
|
|
236
|
-
| `routes.*.conditional.fallback.respond.json` | any JSON value | no | — |
|
|
237
|
-
| `routes.*.proxy` | object | no | unknown keys rejected |
|
|
238
|
-
| `routes.*.proxy.url` | string | yes | maxLength: 8192 |
|
|
239
|
-
| `routes.*.proxy.headers` | object | no | maxProperties: 32 |
|
|
240
|
-
| `routes.*.proxy.headers.*` | one of the shapes below | no | — |
|
|
241
|
-
| `routes.*.proxy.headers.* (option 1)` | string | no | maxLength: 4096 |
|
|
242
|
-
| `routes.*.proxy.headers.* (option 2)` | object | no | unknown keys rejected |
|
|
243
|
-
| `routes.*.proxy.headers.* (option 2).secret` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
244
|
-
| `routes.*.proxy.query` | array | no | maxItems: 32; uniqueItems: true |
|
|
245
|
-
| `routes.*.proxy.query[]` | string | no | minLength: 1; maxLength: 128 |
|
|
246
|
-
| `routes.*.proxy.requestHeaders` | array | no | maxItems: 32; uniqueItems: true |
|
|
247
|
-
| `routes.*.proxy.requestHeaders[]` | string | no | minLength: 1; maxLength: 128 |
|
|
248
|
-
| `routes.*.proxy.responseHeaders` | array | no | maxItems: 32; uniqueItems: true |
|
|
249
|
-
| `routes.*.proxy.responseHeaders[]` | string | no | minLength: 1; maxLength: 128 |
|
|
250
|
-
| `routes.*.signals` | array | no | minItems: 1; maxItems: 8 |
|
|
251
|
-
| `routes.*.signals[]` | object | no | unknown keys rejected |
|
|
252
|
-
| `routes.*.signals[].url` | string | yes | maxLength: 8192 |
|
|
253
|
-
| `routes.*.signals[].headers` | object | no | maxProperties: 32 |
|
|
254
|
-
| `routes.*.signals[].headers.*` | one of the shapes below | no | — |
|
|
255
|
-
| `routes.*.signals[].headers.* (option 1)` | string | no | maxLength: 4096 |
|
|
256
|
-
| `routes.*.signals[].headers.* (option 2)` | object | no | unknown keys rejected |
|
|
257
|
-
| `routes.*.signals[].headers.* (option 2).secret` | string | yes | pattern: "^[A-Za-z_][A-Za-z0-9_]*$" |
|
|
258
|
-
| `routes.*.extension` | string | no | pattern: "^[a-z][a-z0-9-]{0,63}$" |
|
|
259
|
-
| `routes.*.auth` | one of the shapes below | no | — |
|
|
260
|
-
| `routes.*.auth (option 1)` | constant | no | const: true |
|
|
261
|
-
| `routes.*.auth (option 2)` | object | no | unknown keys rejected |
|
|
262
|
-
| `routes.*.auth (option 2).required` | boolean | no | default: true |
|
|
263
|
-
| `routes.*.auth (option 2).role` | string | no | minLength: 1; maxLength: 64 |
|
|
264
|
-
| `routes.*.auth (option 2).permission` | string | no | minLength: 1; maxLength: 128 |
|
|
265
|
-
| `routes.*.auth (option 2).verified` | boolean | no | — |
|
|
266
|
-
| `routes.*.auth (option 2).freshWithinSeconds` | integer | no | minimum: 1; maximum: 3600 |
|
|
267
|
-
| `routes.*.auth (option 2).onDeny` | number / string | no | enum: [401,403,404,"sign-in"] |
|
|
268
|
-
| `routes.*.cache` | object | no | unknown keys rejected |
|
|
269
|
-
| `routes.*.cache.strategy` | string | no | enum: ["no-store","revalidate","public","immutable","swr","sie","micro","cdn-only","private"] |
|
|
270
|
-
| `routes.*.cache.maxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
271
|
-
| `routes.*.cache.staleWhileRevalidate` | integer | no | minimum: 0; maximum: 31536000 |
|
|
272
|
-
| `routes.*.cache.staleIfError` | integer | no | minimum: 0; maximum: 31536000 |
|
|
273
|
-
| `routes.*.cache.cdnMaxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
274
|
-
| `routes.*.cache.originTtl` | integer | no | minimum: 0; maximum: 86400 |
|
|
275
|
-
| `routes.*.cache.vary` | array | no | maxItems: 8; uniqueItems: true |
|
|
276
|
-
| `routes.*.cache.vary[]` | string | no | minLength: 1; maxLength: 128 |
|
|
277
|
-
| `routes.*.cache.statuses` | array | no | maxItems: 16; uniqueItems: true |
|
|
278
|
-
| `routes.*.cache.statuses[]` | integer | no | minimum: 200; maximum: 599 |
|
|
279
|
-
| `routes.*.cache.maxBytes` | integer | no | minimum: 0; maximum: 16777216 |
|
|
280
|
-
| `routes.*.cache.maxEntries` | integer | no | minimum: 1; maximum: 1000000 |
|
|
281
|
-
| `routes.*.cache.force` | boolean | no | default: false |
|
|
282
|
-
| `includes` | array | no | maxItems: 256; uniqueItems: true |
|
|
283
|
-
| `includes[]` | string | no | maxLength: 1024 |
|
|
284
|
-
| `policies` | object | no | unknown keys rejected |
|
|
285
|
-
| `policies.profile` | string | no | pattern: "^[a-z][a-z0-9-]{0,63}$" |
|
|
286
|
-
| `policies.throttle` | one of the shapes below | no | — |
|
|
287
|
-
| `policies.throttle (option 1)` | constant | no | const: false |
|
|
288
|
-
| `policies.throttle (option 2)` | object | no | unknown keys rejected |
|
|
289
|
-
| `policies.throttle (option 2).quota` | integer | no | minimum: 1; maximum: 1000000 |
|
|
290
|
-
| `policies.throttle (option 2).window` | integer | no | minimum: 1; maximum: 86400 |
|
|
291
|
-
| `policies.throttle (option 2).partition` | string | no | enum: ["client","route","client-route"]; default: "client" |
|
|
292
|
-
| `policies.throttle (option 2).status` | integer | no | default: 429; minimum: 400; maximum: 599 |
|
|
293
|
-
| `policies.throttle (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
294
|
-
| `policies.throttle (option 2).maxKeys` | integer | no | default: 100000; minimum: 1000; maximum: 10000000 |
|
|
295
|
-
| `policies.agents` | one of the shapes below | no | — |
|
|
296
|
-
| `policies.agents (option 1)` | constant | no | const: false |
|
|
297
|
-
| `policies.agents (option 2)` | object | no | unknown keys rejected |
|
|
298
|
-
| `policies.agents (option 2).deny` | array | no | maxItems: 32; uniqueItems: true |
|
|
299
|
-
| `policies.agents (option 2).deny[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
300
|
-
| `policies.agents (option 2).allow` | array | no | maxItems: 32; uniqueItems: true |
|
|
301
|
-
| `policies.agents (option 2).allow[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
302
|
-
| `policies.agents (option 2).denyPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
303
|
-
| `policies.agents (option 2).denyPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
304
|
-
| `policies.agents (option 2).allowPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
305
|
-
| `policies.agents (option 2).allowPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
306
|
-
| `policies.agents (option 2).denyEmpty` | boolean | no | default: false |
|
|
307
|
-
| `policies.agents (option 2).status` | integer | no | default: 403; minimum: 400; maximum: 599 |
|
|
308
|
-
| `policies.agents (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
309
|
-
| `policies.security` | one of the shapes below | no | — |
|
|
310
|
-
| `policies.security (option 1)` | constant | no | const: false |
|
|
311
|
-
| `policies.security (option 2)` | object | no | unknown keys rejected |
|
|
312
|
-
| `policies.security (option 2).headers` | string | no | enum: ["oshp","oshp-no-csp","off"]; default: "oshp" |
|
|
313
|
-
| `policies.security (option 2).set` | object | no | maxProperties: 32 |
|
|
314
|
-
| `policies.security (option 2).set.*` | string | no | maxLength: 4096 |
|
|
315
|
-
| `policies.security (option 2).unset` | array | no | maxItems: 32; uniqueItems: true |
|
|
316
|
-
| `policies.security (option 2).unset[]` | string | no | minLength: 1; maxLength: 128 |
|
|
317
|
-
| `policies.compression` | one of the shapes below | no | — |
|
|
318
|
-
| `policies.compression (option 1)` | constant | no | const: false |
|
|
319
|
-
| `policies.compression (option 2)` | object | no | unknown keys rejected |
|
|
320
|
-
| `policies.compression (option 2).encodings` | array | no | default: ["br","gzip"]; minItems: 1; uniqueItems: true |
|
|
321
|
-
| `policies.compression (option 2).encodings[]` | string | no | enum: ["br","gzip","deflate","zstd"] |
|
|
322
|
-
| `policies.compression (option 2).minBytes` | integer | no | default: 1024; minimum: 0; maximum: 1048576 |
|
|
323
|
-
| `policies.compression (option 2).types` | array | no | maxItems: 64; uniqueItems: true |
|
|
324
|
-
| `policies.compression (option 2).types[]` | string | no | minLength: 1; maxLength: 128 |
|
|
325
|
-
| `policies.compression (option 2).level` | integer | no | minimum: 1; maximum: 11 |
|
|
326
|
-
| `policies.compression (option 2).allowWithSecrets` | boolean | no | default: false |
|
|
327
|
-
| `policies.cache` | one of the shapes below | no | — |
|
|
328
|
-
| `policies.cache (option 1)` | constant | no | const: false |
|
|
329
|
-
| `policies.cache (option 2)` | object | no | unknown keys rejected |
|
|
330
|
-
| `policies.cache (option 2).strategy` | string | no | enum: ["no-store","revalidate","public","immutable","swr","sie","micro","cdn-only","private"] |
|
|
331
|
-
| `policies.cache (option 2).maxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
332
|
-
| `policies.cache (option 2).staleWhileRevalidate` | integer | no | minimum: 0; maximum: 31536000 |
|
|
333
|
-
| `policies.cache (option 2).staleIfError` | integer | no | minimum: 0; maximum: 31536000 |
|
|
334
|
-
| `policies.cache (option 2).cdnMaxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
335
|
-
| `policies.cache (option 2).originTtl` | integer | no | minimum: 0; maximum: 86400 |
|
|
336
|
-
| `policies.cache (option 2).vary` | array | no | maxItems: 8; uniqueItems: true |
|
|
337
|
-
| `policies.cache (option 2).vary[]` | string | no | minLength: 1; maxLength: 128 |
|
|
338
|
-
| `policies.cache (option 2).statuses` | array | no | maxItems: 16; uniqueItems: true |
|
|
339
|
-
| `policies.cache (option 2).statuses[]` | integer | no | minimum: 200; maximum: 599 |
|
|
340
|
-
| `policies.cache (option 2).maxBytes` | integer | no | minimum: 0; maximum: 16777216 |
|
|
341
|
-
| `policies.cache (option 2).maxEntries` | integer | no | minimum: 1; maximum: 1000000 |
|
|
342
|
-
| `policies.cache (option 2).force` | boolean | no | default: false |
|
|
343
|
-
| `policies.extensions` | one of the shapes below | no | — |
|
|
344
|
-
| `policies.extensions (option 1)` | constant | no | const: false |
|
|
345
|
-
| `policies.extensions (option 2)` | object | no | maxProperties: 16 |
|
|
346
|
-
| `policies.extensions (option 2).*` | one of the shapes below | no | — |
|
|
347
|
-
| `policies.extensions (option 2).* (option 1)` | constant | no | const: false |
|
|
348
|
-
| `policies.extensions (option 2).* (option 2)` | object | no | — |
|
|
349
|
-
| `profiles` | object | no | maxProperties: 32 |
|
|
350
|
-
| `profiles.*` | object | no | unknown keys rejected |
|
|
351
|
-
| `profiles.*.throttle` | one of the shapes below | no | — |
|
|
352
|
-
| `profiles.*.throttle (option 1)` | constant | no | const: false |
|
|
353
|
-
| `profiles.*.throttle (option 2)` | object | no | unknown keys rejected |
|
|
354
|
-
| `profiles.*.throttle (option 2).quota` | integer | no | minimum: 1; maximum: 1000000 |
|
|
355
|
-
| `profiles.*.throttle (option 2).window` | integer | no | minimum: 1; maximum: 86400 |
|
|
356
|
-
| `profiles.*.throttle (option 2).partition` | string | no | enum: ["client","route","client-route"]; default: "client" |
|
|
357
|
-
| `profiles.*.throttle (option 2).status` | integer | no | default: 429; minimum: 400; maximum: 599 |
|
|
358
|
-
| `profiles.*.throttle (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
359
|
-
| `profiles.*.throttle (option 2).maxKeys` | integer | no | default: 100000; minimum: 1000; maximum: 10000000 |
|
|
360
|
-
| `profiles.*.agents` | one of the shapes below | no | — |
|
|
361
|
-
| `profiles.*.agents (option 1)` | constant | no | const: false |
|
|
362
|
-
| `profiles.*.agents (option 2)` | object | no | unknown keys rejected |
|
|
363
|
-
| `profiles.*.agents (option 2).deny` | array | no | maxItems: 32; uniqueItems: true |
|
|
364
|
-
| `profiles.*.agents (option 2).deny[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
365
|
-
| `profiles.*.agents (option 2).allow` | array | no | maxItems: 32; uniqueItems: true |
|
|
366
|
-
| `profiles.*.agents (option 2).allow[]` | string | no | minLength: 1; maxLength: 1024 |
|
|
367
|
-
| `profiles.*.agents (option 2).denyPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
368
|
-
| `profiles.*.agents (option 2).denyPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
369
|
-
| `profiles.*.agents (option 2).allowPatterns` | array | no | maxItems: 256; uniqueItems: true |
|
|
370
|
-
| `profiles.*.agents (option 2).allowPatterns[]` | string | no | minLength: 1; maxLength: 256 |
|
|
371
|
-
| `profiles.*.agents (option 2).denyEmpty` | boolean | no | default: false |
|
|
372
|
-
| `profiles.*.agents (option 2).status` | integer | no | default: 403; minimum: 400; maximum: 599 |
|
|
373
|
-
| `profiles.*.agents (option 2).mode` | string | no | enum: ["enforce","report"]; default: "enforce" |
|
|
374
|
-
| `profiles.*.security` | one of the shapes below | no | — |
|
|
375
|
-
| `profiles.*.security (option 1)` | constant | no | const: false |
|
|
376
|
-
| `profiles.*.security (option 2)` | object | no | unknown keys rejected |
|
|
377
|
-
| `profiles.*.security (option 2).headers` | string | no | enum: ["oshp","oshp-no-csp","off"]; default: "oshp" |
|
|
378
|
-
| `profiles.*.security (option 2).set` | object | no | maxProperties: 32 |
|
|
379
|
-
| `profiles.*.security (option 2).set.*` | string | no | maxLength: 4096 |
|
|
380
|
-
| `profiles.*.security (option 2).unset` | array | no | maxItems: 32; uniqueItems: true |
|
|
381
|
-
| `profiles.*.security (option 2).unset[]` | string | no | minLength: 1; maxLength: 128 |
|
|
382
|
-
| `profiles.*.compression` | one of the shapes below | no | — |
|
|
383
|
-
| `profiles.*.compression (option 1)` | constant | no | const: false |
|
|
384
|
-
| `profiles.*.compression (option 2)` | object | no | unknown keys rejected |
|
|
385
|
-
| `profiles.*.compression (option 2).encodings` | array | no | default: ["br","gzip"]; minItems: 1; uniqueItems: true |
|
|
386
|
-
| `profiles.*.compression (option 2).encodings[]` | string | no | enum: ["br","gzip","deflate","zstd"] |
|
|
387
|
-
| `profiles.*.compression (option 2).minBytes` | integer | no | default: 1024; minimum: 0; maximum: 1048576 |
|
|
388
|
-
| `profiles.*.compression (option 2).types` | array | no | maxItems: 64; uniqueItems: true |
|
|
389
|
-
| `profiles.*.compression (option 2).types[]` | string | no | minLength: 1; maxLength: 128 |
|
|
390
|
-
| `profiles.*.compression (option 2).level` | integer | no | minimum: 1; maximum: 11 |
|
|
391
|
-
| `profiles.*.compression (option 2).allowWithSecrets` | boolean | no | default: false |
|
|
392
|
-
| `profiles.*.cache` | one of the shapes below | no | — |
|
|
393
|
-
| `profiles.*.cache (option 1)` | constant | no | const: false |
|
|
394
|
-
| `profiles.*.cache (option 2)` | object | no | unknown keys rejected |
|
|
395
|
-
| `profiles.*.cache (option 2).strategy` | string | no | enum: ["no-store","revalidate","public","immutable","swr","sie","micro","cdn-only","private"] |
|
|
396
|
-
| `profiles.*.cache (option 2).maxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
397
|
-
| `profiles.*.cache (option 2).staleWhileRevalidate` | integer | no | minimum: 0; maximum: 31536000 |
|
|
398
|
-
| `profiles.*.cache (option 2).staleIfError` | integer | no | minimum: 0; maximum: 31536000 |
|
|
399
|
-
| `profiles.*.cache (option 2).cdnMaxAge` | integer | no | minimum: 0; maximum: 31536000 |
|
|
400
|
-
| `profiles.*.cache (option 2).originTtl` | integer | no | minimum: 0; maximum: 86400 |
|
|
401
|
-
| `profiles.*.cache (option 2).vary` | array | no | maxItems: 8; uniqueItems: true |
|
|
402
|
-
| `profiles.*.cache (option 2).vary[]` | string | no | minLength: 1; maxLength: 128 |
|
|
403
|
-
| `profiles.*.cache (option 2).statuses` | array | no | maxItems: 16; uniqueItems: true |
|
|
404
|
-
| `profiles.*.cache (option 2).statuses[]` | integer | no | minimum: 200; maximum: 599 |
|
|
405
|
-
| `profiles.*.cache (option 2).maxBytes` | integer | no | minimum: 0; maximum: 16777216 |
|
|
406
|
-
| `profiles.*.cache (option 2).maxEntries` | integer | no | minimum: 1; maximum: 1000000 |
|
|
407
|
-
| `profiles.*.cache (option 2).force` | boolean | no | default: false |
|
|
408
|
-
| `profiles.*.extensions` | one of the shapes below | no | — |
|
|
409
|
-
| `profiles.*.extensions (option 1)` | constant | no | const: false |
|
|
410
|
-
| `profiles.*.extensions (option 2)` | object | no | maxProperties: 16 |
|
|
411
|
-
| `profiles.*.extensions (option 2).*` | one of the shapes below | no | — |
|
|
412
|
-
| `profiles.*.extensions (option 2).* (option 1)` | constant | no | const: false |
|
|
413
|
-
| `profiles.*.extensions (option 2).* (option 2)` | object | no | — |
|
|
414
|
-
| `site` | object | no | unknown keys rejected |
|
|
415
|
-
| `site.robots` | object | no | unknown keys rejected |
|
|
416
|
-
| `site.robots.disallow` | array | no | maxItems: 1024; uniqueItems: true |
|
|
417
|
-
| `site.robots.disallow[]` | string | no | minLength: 1; maxLength: 2048 |
|
|
418
|
-
| `site.robots.allow` | array | no | maxItems: 1024; uniqueItems: true |
|
|
419
|
-
| `site.robots.allow[]` | string | no | minLength: 1; maxLength: 2048 |
|
|
420
|
-
| `site.robots.sitemap` | boolean | no | — |
|
|
421
|
-
| `site.robots.extra` | array | no | maxItems: 1024 |
|
|
422
|
-
| `site.robots.extra[]` | string | no | maxLength: 2048 |
|
|
423
|
-
| `site.sitemap` | one of the shapes below | no | — |
|
|
424
|
-
| `site.sitemap (option 1)` | constant | no | const: true |
|
|
425
|
-
| `site.sitemap (option 2)` | object | no | unknown keys rejected |
|
|
426
|
-
| `site.sitemap (option 2).exclude` | array | no | maxItems: 1024; uniqueItems: true |
|
|
427
|
-
| `site.sitemap (option 2).exclude[]` | string | no | minLength: 1; maxLength: 2048 |
|
|
428
|
-
| `site.sitemap (option 2).changefreq` | string | no | enum: ["always","hourly","daily","weekly","monthly","yearly","never"] |
|
|
429
|
-
| `site.sitemap (option 2).priority` | number | no | minimum: 0; maximum: 1 |
|
|
430
|
-
| `site.favicon` | string | no | minLength: 1; maxLength: 1024 |
|
|
431
|
-
| `site.securityTxt` | object | no | unknown keys rejected |
|
|
432
|
-
| `site.securityTxt.contact` | array | yes | minItems: 1; maxItems: 64 |
|
|
433
|
-
| `site.securityTxt.contact[]` | string | no | minLength: 1; maxLength: 2048 |
|
|
434
|
-
| `site.securityTxt.expires` | string | yes | pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$" |
|
|
435
|
-
| `site.securityTxt.policy` | array | no | maxItems: 64 |
|
|
436
|
-
| `site.securityTxt.policy[]` | string | no | maxLength: 2048; pattern: "^https://" |
|
|
437
|
-
| `site.securityTxt.acknowledgments` | array | no | maxItems: 64 |
|
|
438
|
-
| `site.securityTxt.acknowledgments[]` | string | no | maxLength: 2048; pattern: "^https://" |
|
|
439
|
-
| `site.securityTxt.preferredLanguages` | array | no | minItems: 1; maxItems: 64 |
|
|
440
|
-
| `site.securityTxt.preferredLanguages[]` | string | no | minLength: 2; maxLength: 35 |
|
|
441
|
-
| `site.securityTxt.canonical` | array | no | maxItems: 64 |
|
|
442
|
-
| `site.securityTxt.canonical[]` | string | no | maxLength: 2048; pattern: "^https://" |
|
|
443
|
-
| `site.securityTxt.encryption` | array | no | maxItems: 64 |
|
|
444
|
-
| `site.securityTxt.encryption[]` | string | no | minLength: 1; maxLength: 2048 |
|
|
445
|
-
| `site.llms` | string | no | minLength: 1; maxLength: 1024 |
|
|
446
|
-
| `extensions` | object | no | maxProperties: 16 |
|
|
447
|
-
| `extensions.*` | object | no | unknown keys rejected |
|
|
448
|
-
| `extensions.*.version` | constant | yes | const: "1" |
|
|
449
|
-
| `extensions.*.config` | object | yes | — |
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Historical record
|
|
2
|
-
|
|
3
|
-
Archived 2026-09-19. This records an earlier implementation or proposal, not
|
|
4
|
-
current instructions. See the [current roadmap](../../../ROADMAP.md),
|
|
5
|
-
[current contract](../../SPECIFICATION.md) and [open decisions](../../OPEN-DECISIONS.md).
|
|
6
|
-
Remaining acceptance work is not declared complete by archiving this record.
|
|
7
|
-
|
|
8
|
-
<!-- trust-model-prose: historical-file -->
|
|
9
|
-
<!-- guidance-claims: ignore-file -->
|
|
10
|
-
|
|
11
|
-
# Extension implementation sequence
|
|
12
|
-
|
|
13
|
-
PR #54 records the auth, admin, UI and extension direction. Implementation is
|
|
14
|
-
incremental; the spikes are proposals, not the implemented project schema.
|
|
15
|
-
The implemented specification remains authoritative. This sequence incorporates
|
|
16
|
-
the architectural review rather than treating contradictory spike examples as
|
|
17
|
-
requirements.
|
|
18
|
-
|
|
19
|
-
## Invariants
|
|
20
|
-
|
|
21
|
-
- Operators explicitly install trusted host extensions; project YAML never loads
|
|
22
|
-
host modules or chooses packages. Application code remains isolated in WASM.
|
|
23
|
-
- Authentication credentials stay in host processing. Guest Request headers and
|
|
24
|
-
header-derived parameters must not expose operator-declared credential headers,
|
|
25
|
-
including on public routes receiving a session cookie.
|
|
26
|
-
- Session and one-time-token changes have explicit concurrency semantics. Define
|
|
27
|
-
atomic operations before selecting a database abstraction; multi-record
|
|
28
|
-
operations cannot rely on a same-collection transaction promise.
|
|
29
|
-
- Passwords and bearer credentials use appropriate hashes. TOTP requires protected
|
|
30
|
-
recoverable key material and an operator key rotation/backup contract.
|
|
31
|
-
- Authentication forms and submission destinations belong to trusted extension
|
|
32
|
-
code. Project styling does not imply permission to replace security controls.
|
|
33
|
-
- Administrative authorization is enforced by the API, including subject-level
|
|
34
|
-
restrictions, self-promotion and last-administrator protections.
|
|
35
|
-
- Unsupported target capabilities fail explicitly. Live provider deployment
|
|
36
|
-
testing remains deferred and non-blocking; local tests do not prove deployment.
|
|
37
|
-
|
|
38
|
-
## Delivery order
|
|
39
|
-
|
|
40
|
-
1. **Credential boundary:** add an explicit host-plugin declaration for headers
|
|
41
|
-
withheld from guest requests and parameter resolution. Preserve originals for
|
|
42
|
-
host authentication, cache decisions and policy processing. Test functions,
|
|
43
|
-
middleware and routes without an authentication requirement.
|
|
44
|
-
2. **Extension registration:** explicit operator registry, versioned configuration
|
|
45
|
-
validation, route ownership/collision rules and capability reporting. No
|
|
46
|
-
automatic project host-file execution. Define policy ordering before adding
|
|
47
|
-
an auth policy.
|
|
48
|
-
3. **Session slice:** one supported login method, trusted login/logout forms,
|
|
49
|
-
protected page and JSON routes, session lookup/revocation, CSRF and no-store
|
|
50
|
-
behavior. Evaluate a maintained authentication implementation behind an
|
|
51
|
-
adapter before writing protocol engines. Define durable atomic store methods
|
|
52
|
-
and test concurrent redemption, expiry and interrupted operations.
|
|
53
|
-
4. **Administrative API and CLI:** user lookup and session revocation first;
|
|
54
|
-
audit records and narrowly scoped permissions. Add role/recovery operations
|
|
55
|
-
only with object-level rules and concurrency tests.
|
|
56
|
-
5. **UI and console:** extract components from real auth/admin flows; choose a
|
|
57
|
-
constrained renderer and asset ownership model; verify keyboard and assistive
|
|
58
|
-
technology behavior as well as automated accessibility checks.
|
|
59
|
-
6. **Additional methods and targets:** passkeys, OIDC, MFA, recovery and imports
|
|
60
|
-
each receive state-machine, abuse-budget and portability tests. Preserve
|
|
61
|
-
verification of existing credential formats across target migrations.
|
|
62
|
-
|
|
63
|
-
## Status
|
|
64
|
-
|
|
65
|
-
PR #54 is merged. The first implementation adds the operator-only
|
|
66
|
-
`Plugin.credentialHeaders` boundary, documented in [Plugins](../../PLUGINS.md).
|
|
67
|
-
The remaining items are pending; none of this document declares end-user auth,
|
|
68
|
-
admin routes, extension YAML, or a generic project store available today.
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
# Historical record
|
|
2
|
-
|
|
3
|
-
Archived 2026-09-19. This records an earlier implementation or proposal, not
|
|
4
|
-
current instructions. See the [current roadmap](../../../ROADMAP.md),
|
|
5
|
-
[current contract](../../SPECIFICATION.md) and [open decisions](../../OPEN-DECISIONS.md).
|
|
6
|
-
Remaining acceptance work is not declared complete by archiving this record.
|
|
7
|
-
|
|
8
|
-
<!-- trust-model-prose: historical-file -->
|
|
9
|
-
<!-- guidance-claims: ignore-file -->
|
|
10
|
-
|
|
11
|
-
# Private management and durable mutation audit
|
|
12
|
-
|
|
13
|
-
> **Retired.** This page describes the management API and mutation audit of
|
|
14
|
-
> core's native link store. That store, its `urlcode links` CLI and this
|
|
15
|
-
> management listener were removed from core when `link` was extracted, and the
|
|
16
|
-
> `urlcode-dynamic-link` package that received them has since been retired and
|
|
17
|
-
> unpublished. Nothing in the current runtime exposes this surface. The page is
|
|
18
|
-
> kept because the security reasoning — loopback-only binding, operator-owned
|
|
19
|
-
> credential policy, transactional mutation audit — is referenced by
|
|
20
|
-
> [security audit](../../SECURITY-AUDIT.md) and applies to any component that
|
|
21
|
-
> reintroduces a management listener.
|
|
22
|
-
|
|
23
|
-
Management binds only `127.0.0.1` or `::1`. Use an authenticated private tunnel
|
|
24
|
-
(e.g. SSH/VPN with loopback forwarding); never publish its port through a public
|
|
25
|
-
proxy or container port mapping. This is operator management, not an end-user
|
|
26
|
-
account service. Browser Origin requests remain rejected.
|
|
27
|
-
|
|
28
|
-
## Individual credentials
|
|
29
|
-
|
|
30
|
-
Use `urlcode links api --project ./my-links --store /operator/links.sqlite
|
|
31
|
-
--auth-file /operator/management.json --host 127.0.0.1 --port 3001` (one line).
|
|
32
|
-
The policy is operator-owned, outside the application, at most 64 KiB and mode
|
|
33
|
-
600 on POSIX. Protect its parent directory and apply equivalent Windows ACLs.
|
|
34
|
-
It is not YAML and must never be placed in the application or Git.
|
|
35
|
-
|
|
36
|
-
Generate each token with `node -e "console.log(require('node:crypto').randomBytes(32).toString('base64url'))"`
|
|
37
|
-
on a trusted operator machine. Deliver it through your secret manager. Hash the
|
|
38
|
-
raw token using SHA-256 without a newline; the server expects `Authorization:
|
|
39
|
-
Bearer <token>`. Tokens must contain 43–256 base64url characters. Never use a
|
|
40
|
-
human password as a token. This synthetic policy illustrates the shape; replace
|
|
41
|
-
the hash with the real token hash and choose a short operational expiry:
|
|
42
|
-
|
|
43
|
-
```json
|
|
44
|
-
{
|
|
45
|
-
"version": 1,
|
|
46
|
-
"credentials": [{
|
|
47
|
-
"id": "operator-alice",
|
|
48
|
-
"sha256": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
49
|
-
"expires": "2026-10-01T00:00:00Z",
|
|
50
|
-
"collections": ["links"],
|
|
51
|
-
"actions": ["get", "list", "create", "update", "delete"]
|
|
52
|
-
}]
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
At most 128 credentials; unique IDs and hashes; explicit collection and action
|
|
57
|
-
allowlists with no wildcards. Readers should receive only `get` and `list`.
|
|
58
|
-
An expired, removed or `"revoked": true` credential gets 401; a valid credential
|
|
59
|
-
outside its scope gets 403. The entire policy is validated on every authenticated
|
|
60
|
-
request. Malformed/unreadable policy fails closed with 503, without retaining an
|
|
61
|
-
old permissive copy. Write a replacement file with mode 600 and atomically rename
|
|
62
|
-
it over the policy. No restart is needed. Requests already authorized may finish;
|
|
63
|
-
revocation does not cancel an in-flight transaction. Credential administration is
|
|
64
|
-
an operator filesystem action, never exposed through this HTTP API.
|
|
65
|
-
|
|
66
|
-
Legacy `--token-file` remains available for local compatibility, with full access
|
|
67
|
-
to that listener's collection and actor `legacy-shared`. Prefer `--auth-file` for
|
|
68
|
-
attribution, expiry and revocation. They are mutually exclusive. These bearer
|
|
69
|
-
credentials do not establish verified human identity, MFA, SSO or session login.
|
|
70
|
-
Host administrators and custom embedding code remain trusted operators.
|
|
71
|
-
|
|
72
|
-
## Audit durability and recovery
|
|
73
|
-
|
|
74
|
-
The built-in SQLite writer creates an additive `urlcode_link_audit` table when
|
|
75
|
-
opening a store. Every successful create/update/delete (including CLI and embedded
|
|
76
|
-
store calls) records revision, UTC timestamp, actor, request ID, collection,
|
|
77
|
-
action and SHA-256 of the short code in the **same transaction** as the mutation.
|
|
78
|
-
The default local CLI actor is `local-operator`. Scoped HTTP management requires
|
|
79
|
-
an adapter explicitly declaring atomic audit support; the built-in store provides it.
|
|
80
|
-
|
|
81
|
-
An audit insert failure rolls back both mutation and revision. Conditional-write
|
|
82
|
-
conflicts and rejected requests produce no successful-mutation row. HTTP request
|
|
83
|
-
logs still describe failed/aborted requests and remain best effort. A client timeout
|
|
84
|
-
may follow a committed transaction: reconcile the revision and request ID before
|
|
85
|
-
retrying. A lost HTTP reply is not evidence that the transaction was rolled back.
|
|
86
|
-
|
|
87
|
-
Inspect the journal with an operator-only SQLite client, for example:
|
|
88
|
-
|
|
89
|
-
```sql
|
|
90
|
-
SELECT revision, timestamp, actor, request_id, collection, action, code_sha256
|
|
91
|
-
FROM urlcode_link_audit WHERE revision > 0 ORDER BY revision LIMIT 100;
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
No token, URL, request body or raw short code is stored in the journal. Code hashes
|
|
95
|
-
are correlatable and guessable for short codes; restrict access accordingly.
|
|
96
|
-
This is a durable local transaction journal, **not tamper-evident external storage**.
|
|
97
|
-
An administrator with database access can change it. Export ordered revisions to
|
|
98
|
-
your protected collector/backup system and monitor lag, gaps and disk/WAL growth.
|
|
99
|
-
There is no automatic pruning: define retention and verify archival before any
|
|
100
|
-
operator purge. Keep audit records in backups. User_version remains 1 because
|
|
101
|
-
this table is additive; older readers work, but older writers do not emit audit
|
|
102
|
-
rows. Never roll a management writer back to an unaudited revision.
|