-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcatalog.schema.json
More file actions
330 lines (330 loc) · 15.4 KB
/
Copy pathcatalog.schema.json
File metadata and controls
330 lines (330 loc) · 15.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/davidwkeith/workers/catalog.schema.json",
"title": "Worker catalog",
"description": "Machine-readable manifest of every mountable worker this monorepo ships, consumed by composing apps (e.g. Anglesite's Workers tab and wrangler-config generation). Validated by scripts/catalog-gate.mjs; documented in spec/catalog.md. Worker ids are forever-stable: composing apps persist user state against them.",
"type": "object",
"required": ["workers"],
"properties": {
"$schema": { "type": "string" },
"description": { "type": "string" },
"workers": {
"type": "array",
"items": { "$ref": "#/definitions/worker" }
},
"libraries": {
"type": "object",
"description": "Publishable workspace packages that are deliberately NOT catalog workers (reusable libraries), each with a one-line reason. Every publishable package must appear either here or as a worker entry — enforced by scripts/catalog-gate.mjs.",
"additionalProperties": { "type": "string", "minLength": 1 }
}
},
"additionalProperties": false,
"definitions": {
"worker": {
"type": "object",
"required": [
"id",
"package",
"displayName",
"description",
"group",
"binding",
"resources"
],
"properties": {
"id": {
"type": "string",
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
"description": "Forever-stable kebab-case identifier. Composing apps persist activation state against it; renaming is a breaking change even pre-1.0."
},
"package": {
"type": "string",
"pattern": "^@dwk/",
"description": "The npm package that implements this worker."
},
"displayName": { "type": "string", "minLength": 1 },
"description": { "type": "string", "minLength": 1 },
"group": {
"type": "string",
"minLength": 1,
"description": "Free-text grouping key composing apps section by. Never an enum: apps must not hardcode group names."
},
"binding": { "$ref": "#/definitions/binding" },
"resources": {
"type": "array",
"items": { "$ref": "#/definitions/resource" },
"description": "Cloudflare bindings the composed Worker must declare for this worker, with wrangler-config fidelity (DO class names, queue consumers, secrets). Binding names shared across entries (e.g. AUTH_DB) are the same binding, declared once in the composed config."
},
"requires": {
"type": "array",
"items": { "type": "string" },
"description": "Catalog ids of workers that must also be active for this one to function (e.g. webdav requires solid-pod)."
},
"configFields": {
"type": "array",
"items": { "$ref": "#/definitions/configField" },
"description": "Owner-configurable factory-config settings (issue #470): the subset of this package's factory config a composing app surfaces as site-owner settings and writes into the composed Worker's config. Each field's key is the dot-path where the value lands in the factory config object. Deliberately not the whole config surface — code-level config (base URL, key material, callbacks) stays documented per package in spec/packages/."
},
"routes": {
"type": "array",
"items": { "$ref": "#/definitions/route" },
"description": "HTTP route claims (issue #256): the canonical paths this worker's handler owns when mounted at its default location. The composing app turns the active workers' claims into selective Worker-first routing (e.g. wrangler [assets].run_worker_first). Claims from different workers must never overlap; claims within one worker may (its handler sub-routes)."
},
"triggers": {
"type": "array",
"items": { "$ref": "#/definitions/trigger" },
"description": "Scheduled (cron) trigger claims (issue #265): background jobs the composed Worker must run whenever this worker is active, independent of HTTP routing — a scheduled event is never request-triggered. Each claim becomes a wrangler triggers.crons entry plus a scheduled() export wired to the named factory's handler."
}
},
"additionalProperties": false
},
"configFieldKey": {
"type": "string",
"pattern": "^[A-Za-z_$][A-Za-z0-9_$]*(\\.[A-Za-z_$][A-Za-z0-9_$]*)*$",
"description": "Dot-path into the package's factory config object where the value lands (e.g. \"actor.type\", \"moderators\"). Stable like worker ids: composing apps persist owner settings against it."
},
"configFieldRelevantWhen": {
"type": "object",
"required": ["key", "equals"],
"properties": {
"key": {
"type": "string",
"minLength": 1,
"description": "The key of another config field on the same worker entry this field's relevance depends on."
},
"equals": {
"type": "string",
"minLength": 1,
"description": "The value the referenced field must hold for this field to be relevant. For an enum reference, one of its declared values."
}
},
"additionalProperties": false
},
"configField": {
"description": "One owner-configurable setting (issue #470). \"enum\" fields pick one of a closed value set; \"string-list\" fields hold an owner-edited list of strings. A field with relevantWhen only applies while the referenced field holds the given value (e.g. moderators only for a Group actor).",
"oneOf": [
{
"type": "object",
"required": ["key", "displayName", "description", "type", "values"],
"properties": {
"key": { "$ref": "#/definitions/configFieldKey" },
"displayName": { "type": "string", "minLength": 1 },
"description": { "type": "string", "minLength": 1 },
"type": { "const": "enum" },
"values": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": { "type": "string", "minLength": 1 },
"description": "The closed set of allowed values."
},
"default": {
"type": "string",
"minLength": 1,
"description": "The value the package assumes when the field is not configured. Must be one of \"values\"."
},
"relevantWhen": {
"$ref": "#/definitions/configFieldRelevantWhen"
},
"specificationURL": {
"type": "string",
"format": "uri",
"description": "The specification governing the capability this field enables (e.g. FEP-1b12 for a Group actor)."
}
},
"additionalProperties": false
},
{
"type": "object",
"required": ["key", "displayName", "description", "type"],
"properties": {
"key": { "$ref": "#/definitions/configFieldKey" },
"displayName": { "type": "string", "minLength": 1 },
"description": { "type": "string", "minLength": 1 },
"type": { "const": "string-list" },
"itemFormat": {
"enum": ["iri"],
"description": "Validation format for each list item; \"iri\" means each entry must parse as an absolute IRI (e.g. an ActivityPub actor IRI). Omitted means free-form strings."
},
"relevantWhen": {
"$ref": "#/definitions/configFieldRelevantWhen"
},
"specificationURL": {
"type": "string",
"format": "uri",
"description": "The specification governing the capability this field enables."
}
},
"additionalProperties": false
}
]
},
"trigger": {
"type": "object",
"required": ["cron", "handler"],
"properties": {
"cron": {
"type": "string",
"pattern": "^\\S+ \\S+ \\S+ \\S+ \\S+$",
"description": "Canonical five-field cron expression for the composed wrangler triggers.crons entry. A default cadence, not a protocol requirement — composers may tune it."
},
"handler": {
"type": "string",
"minLength": 1,
"description": "The factory export producing the scheduled handler (e.g. \"createSolidPodGc\") the composer must invoke from the composed Worker's scheduled() export."
},
"bindings": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": { "type": "string", "minLength": 1 },
"description": "Binding names from this worker's own resources the scheduled handler reads. When a listed binding is optional and left unbound, the composer omits the trigger instead of binding it — the handler fails loudly without its bindings."
},
"dedupe": {
"type": "string",
"minLength": 1,
"description": "Shared-job key: triggers on different active workers carrying the same key are one underlying job (e.g. the @dwk/store GC collector solid-pod and remotestorage share over one BLOBS/GC_DB pair). The composer emits one cron entry and wires any one of the declared handlers. Equal keys must declare equal cron expressions."
},
"description": {
"type": "string",
"minLength": 1,
"description": "Human-readable purpose of the job, for composing-app UI."
}
},
"additionalProperties": false
},
"route": {
"type": "object",
"required": ["path", "match", "methods", "handler"],
"properties": {
"path": {
"type": "string",
"pattern": "^/",
"description": "Absolute path, no traversal or empty segments. A prefix claim's path ends with \"/\"."
},
"match": {
"enum": ["exact", "prefix"],
"description": "exact: the path only. prefix: the whole subtree under the trailing-slash path — used only where the standard delegates a subtree, never as a convenience."
},
"methods": {
"type": "array",
"minItems": 1,
"items": { "type": "string", "pattern": "^(?!HEAD$)[A-Z][A-Z-]*$" },
"description": "Allowed methods. The composer answers other methods with 405 + Allow. HEAD is declared via \"head\", never listed here."
},
"head": {
"type": "boolean",
"description": "True when HEAD is supported, mirroring GET's headers without a body. Requires GET among methods."
},
"handler": {
"type": "string",
"minLength": 1,
"description": "The factory export that owns this claim (e.g. \"createWebmention\") — lets the composer correlate a claim with the handler that must be mounted for it."
},
"authorityBound": {
"type": "boolean",
"description": "True when the standard requires this path on the site's canonical origin (well-known discovery documents); the composer must not remount it under a different prefix or host."
},
"validatorID": {
"type": "string",
"minLength": 1,
"description": "Protocol-validator registry reference for this claim (e.g. \"rfc8414\"). Omitted means the route is inventory-only: no conformance claim is made for it. Mirrors Anglesite-app's WorkerRouteClaim.validatorID (Anglesite/Anglesite-app#829)."
},
"authorityBinding": {
"type": "boolean",
"description": "True when responses on this route bind an identity/application/policy to the whole origin — a broader notion than authorityBound's fixed well-known paths (e.g. IndieAuth's /authorize and /token establish the origin's identity even though they are remountable). Mirrors Anglesite-app's WorkerRouteClaim.authorityBinding, which defaults to false when omitted (Anglesite/Anglesite-app#829)."
},
"specificationURL": {
"type": "string",
"format": "uri",
"description": "The governing protocol specification for this claim. Anglesite-app's consumer (WorkerRouteClaims.validate) requires this on every prefix claim; recommended on exact claims too. Mirrors Anglesite-app's WorkerRouteClaim.specificationURL (Anglesite/Anglesite-app#829)."
}
},
"additionalProperties": false
},
"binding": {
"description": "Activation kind. componentTied workers are active iff a bound component is used on ≥1 page (computed by the composing app, never manually toggled); settingsActivated workers are toggled by the site owner.",
"oneOf": [
{
"type": "object",
"required": ["kind", "componentIDs"],
"properties": {
"kind": { "const": "componentTied" },
"componentIDs": {
"type": "array",
"minItems": 1,
"items": { "type": "string", "minLength": 1 },
"description": "Component identifiers in the composing app's site model (Anglesite Site Graph Explorer node IDs) — values coordinated with the app."
}
},
"additionalProperties": false
},
{
"type": "object",
"required": ["kind"],
"properties": {
"kind": { "const": "settingsActivated" }
},
"additionalProperties": false
}
]
},
"resource": {
"oneOf": [
{
"type": "object",
"required": ["type", "binding"],
"properties": {
"type": { "enum": ["d1", "kv", "r2"] },
"binding": { "type": "string", "minLength": 1 },
"optional": { "type": "boolean" }
},
"additionalProperties": false
},
{
"type": "object",
"required": ["type", "binding", "className"],
"properties": {
"type": { "const": "durable-object" },
"binding": { "type": "string", "minLength": 1 },
"className": {
"type": "string",
"minLength": 1,
"description": "The exported Durable Object class name for the wrangler durable_objects binding and migration entry."
},
"sqlite": {
"type": "boolean",
"description": "True when the class uses DO SQLite storage — the first-deploy migration must list it under new_sqlite_classes."
},
"optional": { "type": "boolean" }
},
"additionalProperties": false
},
{
"type": "object",
"required": ["type", "binding"],
"properties": {
"type": { "const": "queue" },
"binding": { "type": "string", "minLength": 1 },
"consumer": {
"type": "boolean",
"description": "True when the package ships a queue consumer the composed Worker must register (a wrangler queues.consumers entry), in addition to the producer binding."
},
"optional": { "type": "boolean" }
},
"additionalProperties": false
},
{
"type": "object",
"required": ["type", "binding"],
"properties": {
"type": { "const": "secret" },
"binding": { "type": "string", "minLength": 1 },
"optional": { "type": "boolean" }
},
"additionalProperties": false
}
]
}
}
}