@agntcms/next 0.2.0
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/dist/assets-Cyt9upqW.d.cts +290 -0
- package/dist/assets-P8OCigDG.d.ts +290 -0
- package/dist/client.cjs +13244 -0
- package/dist/client.d.cts +806 -0
- package/dist/client.d.ts +806 -0
- package/dist/client.mjs +13234 -0
- package/dist/config.cjs +240 -0
- package/dist/config.d.cts +112 -0
- package/dist/config.d.ts +112 -0
- package/dist/config.mjs +194 -0
- package/dist/defineForm-Bp9vzW56.d.ts +71 -0
- package/dist/defineForm-CJ8KZC93.d.cts +71 -0
- package/dist/defineSection-9qQ5ulAH.d.cts +243 -0
- package/dist/defineSection-Kr0pWqMY.d.ts +243 -0
- package/dist/form-BqY0H1V5.d.cts +753 -0
- package/dist/form-BqY0H1V5.d.ts +753 -0
- package/dist/global-CV23g5Bn.d.cts +15 -0
- package/dist/global-CV23g5Bn.d.ts +15 -0
- package/dist/handlers.cjs +2525 -0
- package/dist/handlers.d.cts +330 -0
- package/dist/handlers.d.ts +330 -0
- package/dist/handlers.mjs +2473 -0
- package/dist/index.cjs +372 -0
- package/dist/index.d.cts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.mjs +319 -0
- package/dist/rateLimit-CXptRM_K.d.ts +391 -0
- package/dist/rateLimit-CiROGTLE.d.cts +391 -0
- package/dist/registry-CraTTwT7.d.cts +29 -0
- package/dist/registry-DMujGqt0.d.ts +29 -0
- package/dist/server.cjs +1970 -0
- package/dist/server.d.cts +153 -0
- package/dist/server.d.ts +153 -0
- package/dist/server.mjs +1889 -0
- package/package.json +62 -0
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-field override record. Every property is optional; an absent property
|
|
3
|
+
* means "fall back to the form schema's behaviour for this field":
|
|
4
|
+
*
|
|
5
|
+
* - `label` — visible label. Defaults to `titleCase(fieldName)`.
|
|
6
|
+
* Field NAME (the payload key) is NEVER renamable.
|
|
7
|
+
* - `placeholder` — input placeholder text.
|
|
8
|
+
* - `helpText` — small text rendered below the input.
|
|
9
|
+
* - `hidden` — when `true`, the field is not rendered. If `default`
|
|
10
|
+
* is also set, the default value is included in the
|
|
11
|
+
* submitted payload exactly as if the user had typed it.
|
|
12
|
+
* If no default, the field is omitted entirely (the
|
|
13
|
+
* submit handler will reject if required).
|
|
14
|
+
* - `order` — sort key. Lower values render first. Fields without
|
|
15
|
+
* `order` render last in their original schema order
|
|
16
|
+
* (stable). Ties broken by schema order.
|
|
17
|
+
* - `default` — initial value seeded into the input. Stored as
|
|
18
|
+
* `unknown` because the override record is keyed by
|
|
19
|
+
* raw field name with no compile-time link back to
|
|
20
|
+
* the form schema. The `<Form>` component narrows
|
|
21
|
+
* per descriptor kind at render time and falls back
|
|
22
|
+
* to the schema default (with a one-shot console
|
|
23
|
+
* warning) when the stored shape doesn't match.
|
|
24
|
+
*
|
|
25
|
+
* Both the interface and the property values are `readonly` — overrides
|
|
26
|
+
* are content (snapshot-versioned, JSON-serialisable) and the runtime
|
|
27
|
+
* never mutates them after read.
|
|
28
|
+
*/
|
|
29
|
+
interface FormFieldOverride {
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly placeholder?: string;
|
|
32
|
+
readonly helpText?: string;
|
|
33
|
+
readonly hidden?: boolean;
|
|
34
|
+
readonly order?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Initial value seeded into the field. Type is `unknown` because there
|
|
37
|
+
* is no compile-time link from the keyed field name back to the form
|
|
38
|
+
* schema. See file header for narrowing/fallback policy.
|
|
39
|
+
*/
|
|
40
|
+
readonly default?: unknown;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Map from field name to override record. Keys are the form schema's
|
|
44
|
+
* raw field names (the payload keys). Fields not present in the map use
|
|
45
|
+
* schema defaults.
|
|
46
|
+
*
|
|
47
|
+
* Stored as a plain `Record` rather than `Readonly<Record<...>>` so it
|
|
48
|
+
* round-trips through `JSON.parse` cleanly (parsed objects are plain
|
|
49
|
+
* mutable objects). The runtime treats it as read-only by convention.
|
|
50
|
+
*/
|
|
51
|
+
type FormFieldOverrides = Record<string, FormFieldOverride>;
|
|
52
|
+
/**
|
|
53
|
+
* A field descriptor a section author uses to expose per-section-instance
|
|
54
|
+
* form overrides as content. The `formName` references a registered
|
|
55
|
+
* `FormDefinition` by name (NOT a function reference, so the value is
|
|
56
|
+
* RSC-serialisable and can travel through the section data record like
|
|
57
|
+
* any other field).
|
|
58
|
+
*
|
|
59
|
+
* NOT allowed inside a form schema (forbidden via `FORM_FORBIDDEN_KINDS`
|
|
60
|
+
* in `domain/form.ts`). Forms cannot contain a form-overrides field —
|
|
61
|
+
* that would be a recursive content shape with no ergonomic editor UI.
|
|
62
|
+
*
|
|
63
|
+
* The descriptor's runtime value type is `FormFieldOverrides` (see
|
|
64
|
+
* `FieldValueFor` in `domain/schema.ts`).
|
|
65
|
+
*/
|
|
66
|
+
interface FormOverridesFieldDescriptor {
|
|
67
|
+
readonly kind: 'formOverrides';
|
|
68
|
+
/**
|
|
69
|
+
* Name of the form whose fields this descriptor overrides. Must match
|
|
70
|
+
* a form registered in `defineConfig({ forms: [...] })`. The runtime
|
|
71
|
+
* does NOT validate this at section-definition time (the form
|
|
72
|
+
* registry isn't visible to `defineSection`); the editor widget shows
|
|
73
|
+
* a "form not found" message instead of crashing.
|
|
74
|
+
*/
|
|
75
|
+
readonly formName: string;
|
|
76
|
+
/**
|
|
77
|
+
* Default override map for a freshly inserted section. Defaults to
|
|
78
|
+
* `{}` (i.e. all fields fall back to schema defaults) when omitted —
|
|
79
|
+
* the conditional spread in `FormOverridesField()` keeps the property
|
|
80
|
+
* absent under `exactOptionalPropertyTypes`.
|
|
81
|
+
*/
|
|
82
|
+
readonly default?: FormFieldOverrides;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Factory for a `FormOverridesFieldDescriptor`.
|
|
86
|
+
*
|
|
87
|
+
* `formName` matches the `name` of the `FormDefinition` produced by
|
|
88
|
+
* `defineForm()`. The factory itself does NOT validate that the name
|
|
89
|
+
* resolves to a registered form — registry lookup happens lazily in
|
|
90
|
+
* the editor widget, with a graceful "form not found" message.
|
|
91
|
+
*
|
|
92
|
+
* Why a factory and not a singleton: every section author binds this
|
|
93
|
+
* descriptor to a specific form name, so there is no useful no-args
|
|
94
|
+
* shape. `LinkField` is a singleton because every link descriptor is
|
|
95
|
+
* structurally identical; `FormOverridesField('contact')` is not.
|
|
96
|
+
*/
|
|
97
|
+
declare const FormOverridesField: (formName: string, opts?: {
|
|
98
|
+
readonly default?: FormFieldOverrides;
|
|
99
|
+
}) => FormOverridesFieldDescriptor;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* A section schema: a record mapping field names to built-in field
|
|
103
|
+
* descriptors. This is the COMPILE-TIME description authors pass to
|
|
104
|
+
* `defineSection` and that the runtime uses to resolve per-field types.
|
|
105
|
+
*
|
|
106
|
+
* Defined as a plain `Record<string, FieldDescriptor>` — deliberately
|
|
107
|
+
* WITHOUT a `Readonly<>` wrapper. The reason: `SectionSchema` is used
|
|
108
|
+
* as a constraint in `extends` position (e.g. `S extends SectionSchema`).
|
|
109
|
+
* Adding `Readonly` forces an index signature onto any schema extending
|
|
110
|
+
* it, which collapses `keyof S` to `string` under mapped types and
|
|
111
|
+
* erases the concrete field names the type machinery depends on. Keeping
|
|
112
|
+
* it as a plain Record lets finite object-literal schemas remain
|
|
113
|
+
* assignable without acquiring an index signature, preserving `keyof S`
|
|
114
|
+
* as the precise union of field-name literals.
|
|
115
|
+
*
|
|
116
|
+
* The `Readonly` safety concern (preventing mutation of schema objects)
|
|
117
|
+
* is a compile-time convenience; the `keyof S` preservation is a
|
|
118
|
+
* correctness requirement for `DataOf<S>`, `PageContent<Mode, S>`, and
|
|
119
|
+
* every mapped type that fans out over schema keys.
|
|
120
|
+
*/
|
|
121
|
+
type SectionSchema = Record<string, FieldDescriptor>;
|
|
122
|
+
/**
|
|
123
|
+
* The runtime value of a `ReferenceField`: a pointer to another page by
|
|
124
|
+
* slug. In v1 references are always page-to-page; richer target kinds
|
|
125
|
+
* (collections, entries, etc.) are out of scope (ARCHITECTURE.md section 12).
|
|
126
|
+
*/
|
|
127
|
+
interface ReferenceValue {
|
|
128
|
+
readonly slug: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Maps a built-in `FieldDescriptor` to the type of its runtime value.
|
|
132
|
+
*
|
|
133
|
+
* This is the authoritative mapping used by both the runtime's
|
|
134
|
+
* `PageContent<Mode, S>` and the section-definition layer's own
|
|
135
|
+
* type machinery.
|
|
136
|
+
*
|
|
137
|
+
* Built-in field -> runtime type:
|
|
138
|
+
* text -> string
|
|
139
|
+
* richText -> string (markdown source)
|
|
140
|
+
* image -> ImageValue (`{ filename, alt }`, see domain/fields.ts)
|
|
141
|
+
* video -> VideoValue (`{ url, aspectRatio? }`, see domain/fields.ts)
|
|
142
|
+
* reference -> ReferenceValue
|
|
143
|
+
* link -> LinkValue (discriminated union; see `domain/fields.ts`)
|
|
144
|
+
* button -> ButtonValue (`{ label, variant, link? }`, see domain/fields.ts)
|
|
145
|
+
* number -> number
|
|
146
|
+
* boolean -> boolean
|
|
147
|
+
* select -> string (one of the descriptor's option values)
|
|
148
|
+
* list -> Array<ListItem<S>> (each item: derived data shape of S
|
|
149
|
+
* plus opaque `_id`)
|
|
150
|
+
* formOverrides -> FormFieldOverrides
|
|
151
|
+
* (record of per-field overrides for
|
|
152
|
+
* a section instance pointing at a
|
|
153
|
+
* named form; see domain/formOverrides.ts)
|
|
154
|
+
*
|
|
155
|
+
* The `list` case recurses through the schema. The recursion has to live
|
|
156
|
+
* on this side of the descriptor/value seam because `ListField<S>`'s
|
|
157
|
+
* value depends on `FieldValueFor` applied to every member of `S`.
|
|
158
|
+
*/
|
|
159
|
+
type FieldValueFor<F extends FieldDescriptor> = F extends TextField ? string : F extends RichTextField ? string : F extends ImageField ? ImageValue : F extends VideoField ? VideoValue : F extends ReferenceField ? ReferenceValue : F extends LinkField ? LinkValue : F extends ButtonField ? ButtonValue : F extends NumberField ? number : F extends BooleanField ? boolean : F extends SelectField ? string : F extends ListField<infer S> ? ReadonlyArray<ListItem<S>> : F extends FormOverridesFieldDescriptor ? FormFieldOverrides : never;
|
|
160
|
+
/**
|
|
161
|
+
* The runtime shape of a single item in a `ListField<S>` value.
|
|
162
|
+
*
|
|
163
|
+
* Each item is the derived per-field record of `S` (every field name
|
|
164
|
+
* resolved through `FieldValueFor`) plus an opaque stable `_id` string.
|
|
165
|
+
* The `_id` is set once when the item is created in the editor and
|
|
166
|
+
* persists for the item's lifetime — this is how the editor tracks
|
|
167
|
+
* items across reorder and delete without using index positions.
|
|
168
|
+
*
|
|
169
|
+
* `_id` is exposed in the runtime value type because section components
|
|
170
|
+
* may need it (e.g. to use as a React key when rendering the array).
|
|
171
|
+
* The underscore prefix signals "framework-managed; don't put authoring
|
|
172
|
+
* data here".
|
|
173
|
+
*/
|
|
174
|
+
type ListItem<S extends SectionSchema> = {
|
|
175
|
+
readonly [K in keyof S]: FieldValueFor<S[K]>;
|
|
176
|
+
} & {
|
|
177
|
+
readonly _id: string;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Runtime value of an image field. Both fields required; empty alt is a
|
|
182
|
+
* validation error. Alt is collected per-usage in the picker modal — it
|
|
183
|
+
* is not stored on disk as metadata, because that experiment (v0.1.16–17)
|
|
184
|
+
* was reverted as over-engineering. Keep alt required to preserve a11y
|
|
185
|
+
* as a hard floor.
|
|
186
|
+
*/
|
|
187
|
+
interface ImageValue {
|
|
188
|
+
readonly filename: string;
|
|
189
|
+
readonly alt: string;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Runtime value of a video field. `url` is the raw URL the author
|
|
193
|
+
* pasted. `aspectRatio` is optional; when absent the rendered iframe
|
|
194
|
+
* defaults to 16:9. The closed string-literal union mirrors the
|
|
195
|
+
* options the picker modal exposes — adding a ratio means updating the
|
|
196
|
+
* union AND the picker's `<select>`. `caption` is an optional short
|
|
197
|
+
* plain-text caption rendered below the iframe; intentionally NOT
|
|
198
|
+
* markdown (see `VideoField` JSDoc).
|
|
199
|
+
*/
|
|
200
|
+
interface VideoValue {
|
|
201
|
+
readonly url: string;
|
|
202
|
+
readonly aspectRatio?: '16:9' | '4:3' | '1:1' | '9:16';
|
|
203
|
+
readonly caption?: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Runtime value of a `LinkField`. Discriminated by `type`:
|
|
207
|
+
*
|
|
208
|
+
* - `internal` carries a `slug` (no leading `/`). Empty string is
|
|
209
|
+
* "not yet selected"; `'home'` is the canonical root page; any
|
|
210
|
+
* other slug renders as `/<slug>` via `hrefOf()`.
|
|
211
|
+
* - `external` carries a full `url` (must start with `http://` or
|
|
212
|
+
* `https://`). Empty string is "not yet entered".
|
|
213
|
+
* - `email` carries an `email` address. `hrefOf()` returns
|
|
214
|
+
* `mailto:<email>` when populated, or `''` when empty so the
|
|
215
|
+
* section component can avoid rendering a stray anchor.
|
|
216
|
+
* - `phone` carries a `phone` string for display (the formatted form
|
|
217
|
+
* authors typed). `hrefOf()` strips non-`[\d+]` characters when
|
|
218
|
+
* producing the `tel:` URI, so `phone` may carry parens, spaces,
|
|
219
|
+
* and hyphens for legibility.
|
|
220
|
+
*
|
|
221
|
+
* `label` is always required (empty string allowed). It is the display
|
|
222
|
+
* text the section component renders.
|
|
223
|
+
*/
|
|
224
|
+
type LinkValue = {
|
|
225
|
+
readonly type: 'internal';
|
|
226
|
+
readonly slug: string;
|
|
227
|
+
readonly label: string;
|
|
228
|
+
} | {
|
|
229
|
+
readonly type: 'external';
|
|
230
|
+
readonly url: string;
|
|
231
|
+
readonly label: string;
|
|
232
|
+
} | {
|
|
233
|
+
readonly type: 'email';
|
|
234
|
+
readonly email: string;
|
|
235
|
+
readonly label: string;
|
|
236
|
+
} | {
|
|
237
|
+
readonly type: 'phone';
|
|
238
|
+
readonly phone: string;
|
|
239
|
+
readonly label: string;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Runtime value of a `ButtonField`.
|
|
243
|
+
*
|
|
244
|
+
* - `label` — visible button text. Required, may be empty (the
|
|
245
|
+
* picker shows a "Click to add label" hint then).
|
|
246
|
+
* - `variant` — a presentation key matching one of the descriptor's
|
|
247
|
+
* declared `variants[].value`. Section components map
|
|
248
|
+
* this to a className. Stored verbatim so a variant
|
|
249
|
+
* removed from the schema after content was authored
|
|
250
|
+
* does not silently rewrite the saved value — the
|
|
251
|
+
* picker surfaces the stale variant as "(missing)" so
|
|
252
|
+
* the editor can fix it.
|
|
253
|
+
* - `link` — OPTIONAL. When present, a discriminated `LinkValue`
|
|
254
|
+
* (the same union used by `LinkField`). Sections decide
|
|
255
|
+
* whether to wrap the rendered button in an `<a>` based
|
|
256
|
+
* on `link !== undefined`.
|
|
257
|
+
*/
|
|
258
|
+
interface ButtonValue {
|
|
259
|
+
readonly label: string;
|
|
260
|
+
readonly variant: string;
|
|
261
|
+
readonly link?: LinkValue;
|
|
262
|
+
}
|
|
263
|
+
/** A single option in a `SelectField`. */
|
|
264
|
+
interface SelectOption {
|
|
265
|
+
readonly value: string;
|
|
266
|
+
readonly label: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The shape of a single seed item declared on `ListField.default`. Authors
|
|
270
|
+
* may omit any field — missing fields fall back to per-kind blanks at
|
|
271
|
+
* build time. `_id` is intentionally excluded: the editor regenerates ids
|
|
272
|
+
* recursively when cloning the default, so a literal id in the schema
|
|
273
|
+
* would be overwritten anyway.
|
|
274
|
+
*/
|
|
275
|
+
type ListItemDefault<S extends SectionSchema> = {
|
|
276
|
+
readonly [K in keyof S]?: FieldValueFor<S[K]>;
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* The closed union of all built-in field descriptors.
|
|
280
|
+
*
|
|
281
|
+
* This is the v1 vocabulary for describing a section's schema. It is closed
|
|
282
|
+
* on purpose: consistency of the editing UI depends on the runtime knowing
|
|
283
|
+
* every possible field type ahead of time.
|
|
284
|
+
*
|
|
285
|
+
* `FormOverridesFieldDescriptor` is section-only: it is a member of this
|
|
286
|
+
* union (so a section schema can carry it) but is explicitly listed in
|
|
287
|
+
* `FORM_FORBIDDEN_KINDS` (see `domain/form.ts`), so a form schema cannot
|
|
288
|
+
* carry one. The descriptor lives in `domain/formOverrides.ts` to keep
|
|
289
|
+
* the override-shape types (`FormFieldOverride`, `FormFieldOverrides`) in
|
|
290
|
+
* the same file as the descriptor that produces them.
|
|
291
|
+
*/
|
|
292
|
+
type FieldDescriptor = TextField | RichTextField | ImageField | VideoField | ReferenceField | LinkField | ButtonField | NumberField | BooleanField | SelectField | ListField | FormOverridesFieldDescriptor;
|
|
293
|
+
/** String literal union of every descriptor's `kind` — useful for maps and tables. */
|
|
294
|
+
type FieldKind = FieldDescriptor['kind'];
|
|
295
|
+
/** Plain inline text (single-line or small multi-line without formatting). */
|
|
296
|
+
interface TextField {
|
|
297
|
+
readonly kind: 'text';
|
|
298
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
299
|
+
readonly default?: string;
|
|
300
|
+
}
|
|
301
|
+
declare const TextField: TextField;
|
|
302
|
+
/** Rich text with inline formatting (bold, links, etc.); serialized as markdown. */
|
|
303
|
+
interface RichTextField {
|
|
304
|
+
readonly kind: 'richText';
|
|
305
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
306
|
+
readonly default?: string;
|
|
307
|
+
}
|
|
308
|
+
declare const RichTextField: RichTextField;
|
|
309
|
+
/**
|
|
310
|
+
* An image stored through the asset adapter.
|
|
311
|
+
*
|
|
312
|
+
* The runtime value is an `ImageValue` object (`{ filename, alt }`). Alt
|
|
313
|
+
* is collected per-usage in the image picker modal and lives in the
|
|
314
|
+
* section's `data` alongside the filename — it is NOT stored on disk as
|
|
315
|
+
* asset metadata (the 0.1.16–0.1.17 sidecar experiment was reverted).
|
|
316
|
+
* Keeping alt required at the descriptor level preserves a11y as a hard
|
|
317
|
+
* floor at authoring time.
|
|
318
|
+
*/
|
|
319
|
+
interface ImageField {
|
|
320
|
+
readonly kind: 'image';
|
|
321
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
322
|
+
readonly default?: ImageValue;
|
|
323
|
+
}
|
|
324
|
+
declare const ImageField: ImageField;
|
|
325
|
+
/**
|
|
326
|
+
* An embedded video referenced by URL.
|
|
327
|
+
*
|
|
328
|
+
* The runtime value is a `VideoValue` object (`{ url, aspectRatio?, caption? }`).
|
|
329
|
+
* Unlike `ImageField`, videos are NOT stored as assets on disk — `url` is a
|
|
330
|
+
* full URL pointing at YouTube / Vimeo / Wistia / Loom (the v1 set of
|
|
331
|
+
* recognised providers). Detection of the embed URL is done by the
|
|
332
|
+
* pure helper `parseVideoUrl()` (`domain/video.ts`); when that helper
|
|
333
|
+
* returns no embed URL, the editor renders a "no video — click to add"
|
|
334
|
+
* placeholder.
|
|
335
|
+
*
|
|
336
|
+
* `aspectRatio` is OPTIONAL on purpose: omitting it means "auto", which
|
|
337
|
+
* the editor and the rendered iframe both interpret as 16:9. Encoding
|
|
338
|
+
* "auto" as the absence of the key (rather than the literal string
|
|
339
|
+
* `'auto'`) keeps `VideoValue` minimal and matches how
|
|
340
|
+
* `exactOptionalPropertyTypes` distinguishes "not set" from "explicitly
|
|
341
|
+
* undefined".
|
|
342
|
+
*
|
|
343
|
+
* `caption` is an optional short plain-text caption rendered below the
|
|
344
|
+
* iframe. It is intentionally PLAIN TEXT (not markdown) — captions are
|
|
345
|
+
* short ("A 2-minute walkthrough") and don't need rich-text features.
|
|
346
|
+
* It travels with the video data so the picker modal can edit URL,
|
|
347
|
+
* ratio, and caption in one place.
|
|
348
|
+
*/
|
|
349
|
+
interface VideoField {
|
|
350
|
+
readonly kind: 'video';
|
|
351
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
352
|
+
readonly default?: VideoValue;
|
|
353
|
+
}
|
|
354
|
+
declare const VideoField: VideoField;
|
|
355
|
+
/** A reference to another page or content entry by id. */
|
|
356
|
+
interface ReferenceField {
|
|
357
|
+
readonly kind: 'reference';
|
|
358
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
359
|
+
readonly default?: string;
|
|
360
|
+
}
|
|
361
|
+
declare const ReferenceField: ReferenceField;
|
|
362
|
+
/**
|
|
363
|
+
* A link with display label, modelled as an explicit choice between an
|
|
364
|
+
* internal page reference, an external URL, an email address, or a
|
|
365
|
+
* phone number.
|
|
366
|
+
*
|
|
367
|
+
* Runtime value is a `LinkValue` discriminated union — see below.
|
|
368
|
+
* The descriptor itself does NOT render an anchor; section components
|
|
369
|
+
* decide how to render. The typical pattern is to compute the href via
|
|
370
|
+
* `hrefOf(link)` and the target/rel pair via `linkAnchorAttrs(link)`
|
|
371
|
+
* (see `domain/link.ts`).
|
|
372
|
+
*
|
|
373
|
+
* Why an explicit `type` discriminator rather than the previous
|
|
374
|
+
* "external?: boolean" flag: each branch carries fundamentally
|
|
375
|
+
* different data (a slug reference, a URL, an email address, a phone
|
|
376
|
+
* number) and the editor renders a different sub-form for each. Having
|
|
377
|
+
* a tagged value-side per branch lets each carry exactly the data it
|
|
378
|
+
* needs without a dual-purpose `href` string that means different
|
|
379
|
+
* things in different modes.
|
|
380
|
+
*/
|
|
381
|
+
interface LinkField {
|
|
382
|
+
readonly kind: 'link';
|
|
383
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
384
|
+
readonly default?: LinkValue;
|
|
385
|
+
}
|
|
386
|
+
declare const LinkField: LinkField;
|
|
387
|
+
/**
|
|
388
|
+
* A numeric value with optional validation hints.
|
|
389
|
+
*
|
|
390
|
+
* `min`/`max`/`step` are HINTS for the editor widget, not enforced at the
|
|
391
|
+
* descriptor level. The runtime never validates — the editor's number
|
|
392
|
+
* input clamps and steps to keep authoring sensible. Storage carries
|
|
393
|
+
* whatever the author committed, including out-of-range values from
|
|
394
|
+
* older content if the descriptor's bounds tighten over time.
|
|
395
|
+
*/
|
|
396
|
+
interface NumberField {
|
|
397
|
+
readonly kind: 'number';
|
|
398
|
+
readonly default?: number;
|
|
399
|
+
readonly min?: number;
|
|
400
|
+
readonly max?: number;
|
|
401
|
+
readonly step?: number;
|
|
402
|
+
}
|
|
403
|
+
declare const NumberField: NumberField;
|
|
404
|
+
/** A boolean toggle. */
|
|
405
|
+
interface BooleanField {
|
|
406
|
+
readonly kind: 'boolean';
|
|
407
|
+
readonly default?: boolean;
|
|
408
|
+
}
|
|
409
|
+
declare const BooleanField: BooleanField;
|
|
410
|
+
/**
|
|
411
|
+
* A choice from a fixed list of options.
|
|
412
|
+
*
|
|
413
|
+
* Runtime value is `string` (one of the option `value`s). We deliberately
|
|
414
|
+
* do NOT type the value as a literal union derived from `options` in v1
|
|
415
|
+
* — that would require `as const` discipline at every author's call
|
|
416
|
+
* site, which is a footgun for the typical author. A generic-tied
|
|
417
|
+
* literal-union variant can be added later without breaking the v1
|
|
418
|
+
* shape.
|
|
419
|
+
*/
|
|
420
|
+
interface SelectField {
|
|
421
|
+
readonly kind: 'select';
|
|
422
|
+
readonly options: readonly SelectOption[];
|
|
423
|
+
readonly default?: string;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Factory for a `SelectField`. The `options` array shape is preserved on
|
|
427
|
+
* the descriptor for the editor widget to render; the runtime value is a
|
|
428
|
+
* plain `string` in v1 (see `SelectField` for why we did not derive a
|
|
429
|
+
* literal union from `options`).
|
|
430
|
+
*/
|
|
431
|
+
declare const SelectField: (options: readonly SelectOption[], opts?: {
|
|
432
|
+
readonly default?: string;
|
|
433
|
+
}) => SelectField;
|
|
434
|
+
/**
|
|
435
|
+
* A styled call-to-action button.
|
|
436
|
+
*
|
|
437
|
+
* Runtime value is a `ButtonValue` ({ label, variant, link? }). The
|
|
438
|
+
* descriptor itself does NOT render styles — variant strings are opaque
|
|
439
|
+
* presentation keys (`'primary'` / `'secondary'` / `'ghost'` / whatever
|
|
440
|
+
* the section declares); section components own their CSS and pick a
|
|
441
|
+
* className from `value.variant` at render time. The framework does
|
|
442
|
+
* NOT enforce a global variant set; each `ButtonField` declaration
|
|
443
|
+
* carries the closed list of variants its section supports.
|
|
444
|
+
*
|
|
445
|
+
* `link` is optional on purpose. A button without a link is a pure UI
|
|
446
|
+
* affordance (e.g. "Open dialog", a future click handler) — separating
|
|
447
|
+
* the styled-CTA concern from the navigation concern keeps `LinkField`
|
|
448
|
+
* pure navigation data and lets sections use `ButtonValue` for both
|
|
449
|
+
* link-CTAs and non-navigating action buttons.
|
|
450
|
+
*
|
|
451
|
+
* Why a separate descriptor instead of `LinkField` + a sibling
|
|
452
|
+
* `SelectField` for the variant: in the editor, label + variant + link
|
|
453
|
+
* belong together. Surfacing them as two unrelated fields forced
|
|
454
|
+
* authors to edit the visible text in one modal and the visual style in
|
|
455
|
+
* another. `ButtonField` collapses that into a single picker modal.
|
|
456
|
+
*/
|
|
457
|
+
interface ButtonField {
|
|
458
|
+
readonly kind: 'button';
|
|
459
|
+
/**
|
|
460
|
+
* The closed list of variants this button supports. The picker modal
|
|
461
|
+
* renders a `<select>` populated from these options; section authors
|
|
462
|
+
* decide what styles their CSS supports. Order is preserved — index 0
|
|
463
|
+
* is the canonical fallback when content has no variant set.
|
|
464
|
+
*/
|
|
465
|
+
readonly variants: ReadonlyArray<SelectOption>;
|
|
466
|
+
/** Override the built-in placeholder used when inserting a new section. */
|
|
467
|
+
readonly default?: ButtonValue;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Factory for a `ButtonField`. The `variants` array shape is preserved
|
|
471
|
+
* verbatim so the picker modal can render the variant `<select>` from
|
|
472
|
+
* the descriptor; the runtime value (`ButtonValue.variant`) is a plain
|
|
473
|
+
* string in v1 (same rationale as `SelectField` — see that JSDoc).
|
|
474
|
+
*
|
|
475
|
+
* If `default.variant` does not match any declared `variants[].value`,
|
|
476
|
+
* the picker still surfaces the stored value as "(missing)" so authors
|
|
477
|
+
* can fix it. We do not validate at factory time: schema-author errors
|
|
478
|
+
* surface at editing time, not at module-load time.
|
|
479
|
+
*/
|
|
480
|
+
declare const ButtonField: (variants: ReadonlyArray<SelectOption>, opts?: {
|
|
481
|
+
readonly default?: ButtonValue;
|
|
482
|
+
}) => ButtonField;
|
|
483
|
+
/**
|
|
484
|
+
* A list of structured items, each shaped by a sub-schema.
|
|
485
|
+
*
|
|
486
|
+
* Runtime value is `Array<ListItem<S>>` where `ListItem<S>` is the
|
|
487
|
+
* derived data shape of `itemSchema` plus an opaque stable `_id` string.
|
|
488
|
+
* The `_id` is generated when an item is first inserted (via the
|
|
489
|
+
* editable widget) and persists for the item's lifetime so the editor
|
|
490
|
+
* can track items across reorder/delete without index churn.
|
|
491
|
+
*
|
|
492
|
+
* `itemSchema` is `SectionSchema` — the same vocabulary as a top-level
|
|
493
|
+
* section's data. This means lists of objects with text/richText/image/
|
|
494
|
+
* link/number/boolean/select fields, and even nested lists. Recursion
|
|
495
|
+
* is allowed but not optimised; deeply nested lists will work but the
|
|
496
|
+
* editor UX is intentionally flat (one level of cards).
|
|
497
|
+
*
|
|
498
|
+
* `min`/`max` are HINTS for the editor widget, not enforced at runtime.
|
|
499
|
+
*
|
|
500
|
+
* `default` (optional) is an array of seed items used when the editor
|
|
501
|
+
* builds a blank instance of a parent item that contains this list — the
|
|
502
|
+
* canonical case is "a new tier comes pre-filled with two feature rows".
|
|
503
|
+
* Each entry is a `Partial` over the item shape so authors can omit fields
|
|
504
|
+
* they don't care about (those fall back to per-kind blanks). `_id` is
|
|
505
|
+
* deliberately NOT part of the default-item shape: the editor mints a
|
|
506
|
+
* fresh `_id` for every cloned entry, recursively, so two consecutive
|
|
507
|
+
* blank-builds never share ids. See `buildBlankItem` in
|
|
508
|
+
* `react/editable/ItemFormEditor.tsx` for the regeneration rule.
|
|
509
|
+
*/
|
|
510
|
+
interface ListField<S extends SectionSchema = SectionSchema> {
|
|
511
|
+
readonly kind: 'list';
|
|
512
|
+
readonly itemSchema: S;
|
|
513
|
+
readonly min?: number;
|
|
514
|
+
readonly max?: number;
|
|
515
|
+
readonly default?: ReadonlyArray<ListItemDefault<S>>;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Factory for a `ListField`. Generic over the item schema so the runtime
|
|
519
|
+
* value type (`FieldValueFor<ListField<S>>`) can include the precise
|
|
520
|
+
* shape of each list item. See `domain/schema.ts` for the recursion.
|
|
521
|
+
*/
|
|
522
|
+
declare const ListField: <S extends SectionSchema>(itemSchema: S, opts?: {
|
|
523
|
+
readonly min?: number;
|
|
524
|
+
readonly max?: number;
|
|
525
|
+
readonly default?: ReadonlyArray<ListItemDefault<S>>;
|
|
526
|
+
}) => ListField<S>;
|
|
527
|
+
|
|
528
|
+
interface Section<T extends string = string, D = unknown> {
|
|
529
|
+
readonly id: string;
|
|
530
|
+
readonly type: T;
|
|
531
|
+
readonly data: D;
|
|
532
|
+
/** When set, this section is a reference to a named global.
|
|
533
|
+
* The runtime resolves `type` and `data` from the global at read time. */
|
|
534
|
+
readonly globalRef?: string;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
interface PageSeo {
|
|
538
|
+
readonly title: string;
|
|
539
|
+
readonly description: string;
|
|
540
|
+
readonly ogImage?: ImageValue;
|
|
541
|
+
readonly canonical?: string;
|
|
542
|
+
}
|
|
543
|
+
interface Page {
|
|
544
|
+
readonly slug: string;
|
|
545
|
+
readonly seo: PageSeo;
|
|
546
|
+
/**
|
|
547
|
+
* Tags for `listPages` filtering. Matching is case-sensitive exact:
|
|
548
|
+
* `tags: ['Post']` does NOT match a query for `tag=post`.
|
|
549
|
+
* (See ARCHITECTURE.md §4.)
|
|
550
|
+
*/
|
|
551
|
+
readonly tags?: readonly string[];
|
|
552
|
+
/** Short summary used by listing sections (PostList etc.). */
|
|
553
|
+
readonly excerpt?: string;
|
|
554
|
+
/** Cover image for listing sections / blog cards. */
|
|
555
|
+
readonly coverImage?: ImageValue;
|
|
556
|
+
/**
|
|
557
|
+
* ISO 8601 publication date used by `listPages` for sorting. When
|
|
558
|
+
* absent, the runtime falls back to the storage adapter's "last
|
|
559
|
+
* modified" timestamp (file mtime for the FS adapter).
|
|
560
|
+
*/
|
|
561
|
+
readonly publishedAt?: string;
|
|
562
|
+
readonly sections: readonly Section[];
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* `Page` without `sections` — the metadata-only projection returned by
|
|
566
|
+
* `listPages`. Used for blog-index-style listing pages where loading
|
|
567
|
+
* every page's full section tree would be wasteful.
|
|
568
|
+
*
|
|
569
|
+
* Defined as `Omit<Page, 'sections'>` so adding a new metadata field to
|
|
570
|
+
* `Page` automatically widens `PageSummary` — no two-place edits.
|
|
571
|
+
*/
|
|
572
|
+
type PageSummary = Omit<Page, 'sections'>;
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Closed union of field descriptors allowed in a form schema in v1.
|
|
576
|
+
*
|
|
577
|
+
* Why this is a strict subset of `FieldDescriptor`:
|
|
578
|
+
* - `image` → file upload is deferred (§6.5, §12).
|
|
579
|
+
* - `video` → forms collect text/numbers/etc. from end users; a
|
|
580
|
+
* public submission carrying an embed URL is a semantic
|
|
581
|
+
* outlier (videos are authoring content, not user input).
|
|
582
|
+
* - `reference` → semantically odd for user input — references are an
|
|
583
|
+
* authoring construct, not a public-site concern.
|
|
584
|
+
* - `list` → payload validation becomes recursive; YAGNI for the
|
|
585
|
+
* newsletter/contact use cases v1 targets.
|
|
586
|
+
*
|
|
587
|
+
* Keeping this set closed at the type level makes the restriction visible
|
|
588
|
+
* to authors at compile time. The runtime check in `defineForm()` provides
|
|
589
|
+
* the same guarantee for callers that erase types via `as`.
|
|
590
|
+
*/
|
|
591
|
+
type FormFieldDescriptor = TextField | RichTextField | NumberField | BooleanField | SelectField | LinkField;
|
|
592
|
+
/**
|
|
593
|
+
* A form schema: a record mapping field names to allowed form-field descriptors.
|
|
594
|
+
*
|
|
595
|
+
* Defined as a plain `Record` (no `Readonly<>`) for the same `keyof S`
|
|
596
|
+
* preservation reason described in `domain/schema.ts`'s `SectionSchema`.
|
|
597
|
+
*/
|
|
598
|
+
type FormSchema = Record<string, FormFieldDescriptor>;
|
|
599
|
+
/**
|
|
600
|
+
* Registration record produced by `defineForm`. The runtime registry
|
|
601
|
+
* (`forms/registry.ts`) stores these keyed by `name`, mirroring the
|
|
602
|
+
* section registry.
|
|
603
|
+
*
|
|
604
|
+
* `honeypot` is the OPTIONAL name of an additional hidden field the
|
|
605
|
+
* frontend renders out-of-schema (e.g. `<input name="website" style="display:none">`).
|
|
606
|
+
* If a non-empty value arrives in a submit payload at that key, the server
|
|
607
|
+
* suppresses the submission silently. On the wire the response is
|
|
608
|
+
* indistinguishable from a successful no-op (200 OK with `{ ok: true,
|
|
609
|
+
* stored: false }`) — by design, so a bot cannot tell from the response
|
|
610
|
+
* whether it was filtered. The `suppressed: 'honeypot'` marker is INTERNAL
|
|
611
|
+
* to the runtime's `SubmitFormResult` discriminant (see
|
|
612
|
+
* `runtime/submitForm.ts`); the submit route handler strips it before
|
|
613
|
+
* returning. The honeypot field name MUST NOT collide with any real schema
|
|
614
|
+
* field name — `defineForm()` enforces this.
|
|
615
|
+
*/
|
|
616
|
+
interface FormDefinition<S extends FormSchema = FormSchema> {
|
|
617
|
+
/** Unique name. Used as the URL-safe identifier in submit/list/read endpoints. */
|
|
618
|
+
readonly name: string;
|
|
619
|
+
/** Field descriptors. */
|
|
620
|
+
readonly schema: S;
|
|
621
|
+
/** Optional honeypot field name (out-of-schema). See type doc. */
|
|
622
|
+
readonly honeypot?: string;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Erased/heterogeneous form definition for use in lists (e.g.
|
|
626
|
+
* `defineConfig({ forms: [Contact, Newsletter] })`). Mirrors the
|
|
627
|
+
* `AnySectionDefinition` pattern in `sections/defineSection.ts`.
|
|
628
|
+
*/
|
|
629
|
+
interface AnyFormDefinition {
|
|
630
|
+
readonly name: string;
|
|
631
|
+
readonly schema: FormSchema;
|
|
632
|
+
readonly honeypot?: string;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Minimal lookup interface for a registry of form definitions.
|
|
636
|
+
*
|
|
637
|
+
* Lives in `domain/` because the runtime (`runtime/submitForm.ts`) needs
|
|
638
|
+
* to depend on "something that can look up a form by name" without having
|
|
639
|
+
* to import from the `forms/` sibling. This keeps the dependency graph
|
|
640
|
+
* `runtime → domain, storage` (ARCHITECTURE.md §8) intact.
|
|
641
|
+
*
|
|
642
|
+
* The concrete registry built by `forms/registry.ts` (`FormRegistry`)
|
|
643
|
+
* structurally satisfies this interface — no wrapping needed at the call
|
|
644
|
+
* site. `definitions` is included so handlers can enumerate registered
|
|
645
|
+
* forms (for `forms/list`).
|
|
646
|
+
*/
|
|
647
|
+
interface FormLookup {
|
|
648
|
+
readonly definitions: ReadonlyArray<AnyFormDefinition>;
|
|
649
|
+
get(name: string): AnyFormDefinition | undefined;
|
|
650
|
+
has(name: string): boolean;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* A single form submission stored by a `SubmissionStorageAdapter`.
|
|
654
|
+
*
|
|
655
|
+
* Shape is intentionally flat:
|
|
656
|
+
* - `formName` selects the form schema this submission belongs to.
|
|
657
|
+
* - `payload` is the validated record of field values, opaque to the
|
|
658
|
+
* storage layer (storage doesn't know schemas; the runtime validates
|
|
659
|
+
* before calling the adapter).
|
|
660
|
+
* - `submittedAt` is an ISO-8601 string. We use a string rather than a
|
|
661
|
+
* `Date` because submissions cross JSON boundaries (route handler →
|
|
662
|
+
* adapter → potentially webhook → potentially admin UI) and
|
|
663
|
+
* `Date.toISOString()` round-tripping has known edge cases.
|
|
664
|
+
* - `id` is an opaque, lex-sortable identifier. The FS adapter uses it
|
|
665
|
+
* as a tie-breaker when two submissions share a `submittedAt`
|
|
666
|
+
* millisecond.
|
|
667
|
+
*
|
|
668
|
+
* Privacy note: the IP address is NOT stored by default (ARCHITECTURE.md
|
|
669
|
+
* §6.5 / §11). Adding it would be a config-flag change.
|
|
670
|
+
*/
|
|
671
|
+
interface Submission {
|
|
672
|
+
readonly formName: string;
|
|
673
|
+
/**
|
|
674
|
+
* Validated payload. Each value type matches the runtime type of its
|
|
675
|
+
* declared `FormFieldDescriptor` (see `formPayloadValueFor`). Stored
|
|
676
|
+
* as `unknown` here so the storage layer stays schema-agnostic.
|
|
677
|
+
*/
|
|
678
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
679
|
+
/** ISO-8601 timestamp of when the submit handler accepted the payload. */
|
|
680
|
+
readonly submittedAt: string;
|
|
681
|
+
/** Lex-sortable opaque identifier (ULID-like). */
|
|
682
|
+
readonly id: string;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Lightweight summary of a stored submission, returned by
|
|
686
|
+
* `SubmissionStorageAdapter.list`. The full payload is fetched on demand
|
|
687
|
+
* via `read` so the AdminModal list view stays cheap even when a form
|
|
688
|
+
* accumulates thousands of entries.
|
|
689
|
+
*/
|
|
690
|
+
interface SubmissionSummary {
|
|
691
|
+
readonly id: string;
|
|
692
|
+
readonly submittedAt: string;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Public adapter-info descriptor surfaced through the runtime so handlers
|
|
696
|
+
* (notably the frozen `forms/list` route) can tell the AdminModal whether
|
|
697
|
+
* submissions are locally readable. Two shapes:
|
|
698
|
+
* - `{ kind: 'fs' }` — local FS submissions; readable.
|
|
699
|
+
* - `{ kind: 'webhook', host }` — webhook adapter; not locally readable.
|
|
700
|
+
*
|
|
701
|
+
* The host is the `URL.host` portion of the configured webhook (no path,
|
|
702
|
+
* no query, no credentials) — surfaced so the AdminModal can render a
|
|
703
|
+
* "POSTed to <host>" hint without leaking secrets.
|
|
704
|
+
*/
|
|
705
|
+
type SubmissionAdapterInfo = {
|
|
706
|
+
readonly kind: 'fs';
|
|
707
|
+
} | {
|
|
708
|
+
readonly kind: 'webhook';
|
|
709
|
+
readonly host: string;
|
|
710
|
+
};
|
|
711
|
+
/**
|
|
712
|
+
* Storage adapter for form submissions (ARCHITECTURE.md §5, §6.5).
|
|
713
|
+
*
|
|
714
|
+
* Implementations:
|
|
715
|
+
* - FS: writes `<root>/<formName>/<submittedAt>-<id>.json`. Default.
|
|
716
|
+
* - Webhook: POSTs each submission to a configured URL; does NOT write
|
|
717
|
+
* to disk. `list`/`read` throw if called (no local copy).
|
|
718
|
+
*
|
|
719
|
+
* `store` is the only mandatory write path. `list`/`read` are required
|
|
720
|
+
* to satisfy AdminModal's "Submissions" tab (Dispatch 2). A webhook-only
|
|
721
|
+
* setup signals "no local copies" by throwing a typed error so the route
|
|
722
|
+
* handler can return a clean 405.
|
|
723
|
+
*
|
|
724
|
+
* `info` is a small introspection field. Frozen route handlers wire the
|
|
725
|
+
* adapter into `createFormsListHandler` so the AdminModal knows whether
|
|
726
|
+
* to attempt `/forms/read` (FS) or render a "remote" hint (webhook).
|
|
727
|
+
* Without it the handler would default to `kind: 'fs'` and the modal
|
|
728
|
+
* would issue 501-returning fetches against a webhook adapter.
|
|
729
|
+
*
|
|
730
|
+
* Implementations MUST NOT throw for "form has no submissions"; `list`
|
|
731
|
+
* MUST return an empty array in that case. `read(formName, id)` MUST
|
|
732
|
+
* return `null` for an unknown id (mirrors `ContentStorageAdapter.readPage`).
|
|
733
|
+
*/
|
|
734
|
+
interface SubmissionStorageAdapter {
|
|
735
|
+
/** Static descriptor of this adapter. See `SubmissionAdapterInfo`. */
|
|
736
|
+
readonly info: SubmissionAdapterInfo;
|
|
737
|
+
/** Persist a submission. Returns void; the runtime stamps id+submittedAt. */
|
|
738
|
+
store(submission: Submission): Promise<void>;
|
|
739
|
+
/** List submissions for a form, newest first. Returns [] if none. */
|
|
740
|
+
list(formName: string): Promise<ReadonlyArray<SubmissionSummary>>;
|
|
741
|
+
/** Read a single submission. Returns `null` if the id is unknown. */
|
|
742
|
+
read(formName: string, id: string): Promise<Submission | null>;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Thrown by adapters that have no local read surface (e.g. webhook-only).
|
|
746
|
+
* The route handler maps this to HTTP 501 / 405 so the AdminModal can
|
|
747
|
+
* surface a helpful message.
|
|
748
|
+
*/
|
|
749
|
+
declare class SubmissionsNotReadableError extends Error {
|
|
750
|
+
constructor(message?: string);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
export { type AnyFormDefinition as A, ButtonField as B, type PageSeo as C, type Section as D, type SelectOption as E, type FormLookup as F, ImageField as I, LinkField as L, NumberField as N, type Page as P, RichTextField as R, type SectionSchema as S, TextField as T, VideoField as V, type FormSchema as a, type FormDefinition as b, type FieldDescriptor as c, type ImageValue as d, type VideoValue as e, ReferenceField as f, type ReferenceValue as g, type LinkValue as h, type ButtonValue as i, BooleanField as j, SelectField as k, ListField as l, type FormOverridesFieldDescriptor as m, type FormFieldOverrides as n, type SubmissionStorageAdapter as o, type FormFieldDescriptor as p, type FormFieldOverride as q, FormOverridesField as r, type Submission as s, type SubmissionAdapterInfo as t, type SubmissionSummary as u, SubmissionsNotReadableError as v, type PageSummary as w, type FieldValueFor as x, type FieldKind as y, type ListItem as z };
|