@agntcms/next 0.3.1 → 0.3.4
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 → assets-B3oNeLdj.d.cts} +1 -1
- package/dist/{assets-P8OCigDG.d.ts → assets-DHumg-X7.d.ts} +1 -1
- package/dist/client.cjs +2831 -4747
- package/dist/client.d.cts +11 -153
- package/dist/client.d.ts +11 -153
- package/dist/client.mjs +4750 -6675
- package/dist/config.cjs +25 -121
- package/dist/config.d.cts +6 -59
- package/dist/config.d.ts +6 -59
- package/dist/config.mjs +25 -114
- package/dist/{defineSection-Kr0pWqMY.d.ts → defineSection-ByG5uwiR.d.cts} +5 -24
- package/dist/{defineSection-9qQ5ulAH.d.cts → defineSection-ChkZCQyQ.d.ts} +5 -24
- package/dist/{rateLimit-CXptRM_K.d.ts → getContent-DAgAn095.d.ts} +3 -132
- package/dist/{rateLimit-CiROGTLE.d.cts → getContent-yK-sARoc.d.cts} +3 -132
- package/dist/handlers.cjs +19 -382
- package/dist/handlers.d.cts +4 -73
- package/dist/handlers.d.ts +4 -73
- package/dist/handlers.mjs +19 -377
- package/dist/index.cjs +1 -109
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.mjs +1 -103
- package/dist/{form-BqY0H1V5.d.cts → page-DXF0_SrY.d.cts} +3 -293
- package/dist/{form-BqY0H1V5.d.ts → page-DXF0_SrY.d.ts} +3 -293
- package/dist/server.cjs +15 -635
- package/dist/server.d.cts +8 -75
- package/dist/server.d.ts +8 -75
- package/dist/server.mjs +11 -618
- package/package.json +1 -1
- package/dist/defineForm-Bp9vzW56.d.ts +0 -71
- package/dist/defineForm-CJ8KZC93.d.cts +0 -71
- package/dist/registry-CraTTwT7.d.cts +0 -29
- package/dist/registry-DMujGqt0.d.ts +0 -29
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SectionSchema,
|
|
1
|
+
import { S as SectionSchema, F as FieldDescriptor, T as TextField, R as RichTextField, I as ImageField, a as ImageValue, V as VideoField, b as VideoValue, c as ReferenceField, d as ReferenceValue, L as LinkField, e as LinkValue, B as ButtonField, f as ButtonValue, N as NumberField, g as BooleanField, h as SelectField, i as ListField } from './page-DXF0_SrY.cjs';
|
|
2
2
|
|
|
3
3
|
declare const __slot: unique symbol;
|
|
4
4
|
/**
|
|
@@ -70,7 +70,6 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
70
70
|
* select → EditableSlot<'select', string>
|
|
71
71
|
* list → EditableSlot<'list', ReadonlyArray<SlotItem<S>>>
|
|
72
72
|
* reference → ReferenceValue (raw — see decision #3)
|
|
73
|
-
* formOverrides → FormFieldOverrides (raw — see decision #4)
|
|
74
73
|
*
|
|
75
74
|
* EDITABILITY_DESIGN.md gates this design. The slot wrapping is the
|
|
76
75
|
* load-bearing change: a slot is not assignable to `React.ReactNode`, so
|
|
@@ -80,11 +79,7 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
80
79
|
*
|
|
81
80
|
* `ReferenceField` stays raw because references are not inline-editable
|
|
82
81
|
* in v1 (decision #3): a slot would force a no-op `<EditableReference>`
|
|
83
|
-
* wrapper without UX value.
|
|
84
|
-
* forms render via a built-in `<Form>` component that reads the schema
|
|
85
|
-
* itself; there is no author-defined component receiving raw form-field
|
|
86
|
-
* values, and therefore no JSX surface where a raw render could leak
|
|
87
|
-
* (decision #4).
|
|
82
|
+
* wrapper without UX value.
|
|
88
83
|
*
|
|
89
84
|
* `FieldDataType` and `FieldValueFor` (`domain/schema.ts`) NO LONGER
|
|
90
85
|
* agree element-by-element: `FieldValueFor` is the bare runtime payload
|
|
@@ -100,13 +95,13 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
100
95
|
* "user-extensible field types" — invariant 5 (CLAUDE.md) forbids a
|
|
101
96
|
* plugin system; this is just the internal seam.
|
|
102
97
|
*/
|
|
103
|
-
type FieldDataType<F extends FieldDescriptor> = F extends TextField ? EditableSlot<'text', string> : F extends RichTextField ? EditableSlot<'richText', string> : F extends ImageField ? EditableSlot<'image', ImageValue> : F extends VideoField ? EditableSlot<'video', VideoValue> : F extends ReferenceField ? ReferenceValue : F extends LinkField ? EditableSlot<'link', LinkValue> : F extends ButtonField ? EditableSlot<'button', ButtonValue> : F extends NumberField ? EditableSlot<'number', number> : F extends BooleanField ? EditableSlot<'boolean', boolean> : F extends SelectField ? EditableSlot<'select', string> : F extends ListField<infer S> ? EditableSlot<'list', ReadonlyArray<SlotItem<S>>> :
|
|
98
|
+
type FieldDataType<F extends FieldDescriptor> = F extends TextField ? EditableSlot<'text', string> : F extends RichTextField ? EditableSlot<'richText', string> : F extends ImageField ? EditableSlot<'image', ImageValue> : F extends VideoField ? EditableSlot<'video', VideoValue> : F extends ReferenceField ? ReferenceValue : F extends LinkField ? EditableSlot<'link', LinkValue> : F extends ButtonField ? EditableSlot<'button', ButtonValue> : F extends NumberField ? EditableSlot<'number', number> : F extends BooleanField ? EditableSlot<'boolean', boolean> : F extends SelectField ? EditableSlot<'select', string> : F extends ListField<infer S> ? EditableSlot<'list', ReadonlyArray<SlotItem<S>>> : never;
|
|
104
99
|
/**
|
|
105
100
|
* Derives the SECTION-COMPONENT prop shape from its schema.
|
|
106
101
|
*
|
|
107
102
|
* Per `FieldDataType`, every editable field becomes an `EditableSlot<K,V>`
|
|
108
|
-
* (so `<h1>{title}</h1>` is a TS error); `ReferenceValue`
|
|
109
|
-
*
|
|
103
|
+
* (so `<h1>{title}</h1>` is a TS error); `ReferenceValue` stays raw.
|
|
104
|
+
* Example:
|
|
110
105
|
*
|
|
111
106
|
* type HeroSchema = { title: TextField; image: ImageField; ref: ReferenceField }
|
|
112
107
|
* DataOf<HeroSchema> ≡ {
|
|
@@ -172,16 +167,6 @@ interface SectionDefinition<S extends SectionSchema, C extends SectionComponent<
|
|
|
172
167
|
* never interprets these — consumers that read a specific field narrow
|
|
173
168
|
* at the call site. */
|
|
174
169
|
readonly defaults: Record<string, unknown>;
|
|
175
|
-
/** Optional list of layout names supported by this section. When present
|
|
176
|
-
* with length >= 2, the preview-mode section picker renders a "Layout"
|
|
177
|
-
* tab so authors can switch the layout without editing JSON. The section
|
|
178
|
-
* component reads the active layout from its `layout` prop; the picker
|
|
179
|
-
* writes that value via the existing per-field save round-trip.
|
|
180
|
-
*
|
|
181
|
-
* Layouts are a SECTION-level concern, not a field descriptor, because
|
|
182
|
-
* they gate structure inside a single component rather than introducing
|
|
183
|
-
* a new field type. See ARCHITECTURE.md §4. */
|
|
184
|
-
readonly layouts?: readonly string[];
|
|
185
170
|
}
|
|
186
171
|
/**
|
|
187
172
|
* The erased/heterogeneous form used by the registry and by
|
|
@@ -208,8 +193,6 @@ interface AnySectionDefinition {
|
|
|
208
193
|
readonly component: (props: never) => unknown;
|
|
209
194
|
/** Pre-computed placeholder values — see `SectionDefinition.defaults`. */
|
|
210
195
|
readonly defaults: Record<string, unknown>;
|
|
211
|
-
/** Optional layout names — see `SectionDefinition.layouts`. */
|
|
212
|
-
readonly layouts?: readonly string[];
|
|
213
196
|
}
|
|
214
197
|
/**
|
|
215
198
|
* Input shape for `defineSection`. Split out so the factory can use a single
|
|
@@ -221,8 +204,6 @@ interface DefineSectionInput<S extends SectionSchema, C extends SectionComponent
|
|
|
221
204
|
readonly category?: string;
|
|
222
205
|
readonly schema: S;
|
|
223
206
|
readonly component: C;
|
|
224
|
-
/** Optional layout names — see `SectionDefinition.layouts`. */
|
|
225
|
-
readonly layouts?: readonly string[];
|
|
226
207
|
}
|
|
227
208
|
/**
|
|
228
209
|
* Type-safe factory for a `SectionDefinition`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SectionSchema,
|
|
1
|
+
import { S as SectionSchema, F as FieldDescriptor, T as TextField, R as RichTextField, I as ImageField, a as ImageValue, V as VideoField, b as VideoValue, c as ReferenceField, d as ReferenceValue, L as LinkField, e as LinkValue, B as ButtonField, f as ButtonValue, N as NumberField, g as BooleanField, h as SelectField, i as ListField } from './page-DXF0_SrY.js';
|
|
2
2
|
|
|
3
3
|
declare const __slot: unique symbol;
|
|
4
4
|
/**
|
|
@@ -70,7 +70,6 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
70
70
|
* select → EditableSlot<'select', string>
|
|
71
71
|
* list → EditableSlot<'list', ReadonlyArray<SlotItem<S>>>
|
|
72
72
|
* reference → ReferenceValue (raw — see decision #3)
|
|
73
|
-
* formOverrides → FormFieldOverrides (raw — see decision #4)
|
|
74
73
|
*
|
|
75
74
|
* EDITABILITY_DESIGN.md gates this design. The slot wrapping is the
|
|
76
75
|
* load-bearing change: a slot is not assignable to `React.ReactNode`, so
|
|
@@ -80,11 +79,7 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
80
79
|
*
|
|
81
80
|
* `ReferenceField` stays raw because references are not inline-editable
|
|
82
81
|
* in v1 (decision #3): a slot would force a no-op `<EditableReference>`
|
|
83
|
-
* wrapper without UX value.
|
|
84
|
-
* forms render via a built-in `<Form>` component that reads the schema
|
|
85
|
-
* itself; there is no author-defined component receiving raw form-field
|
|
86
|
-
* values, and therefore no JSX surface where a raw render could leak
|
|
87
|
-
* (decision #4).
|
|
82
|
+
* wrapper without UX value.
|
|
88
83
|
*
|
|
89
84
|
* `FieldDataType` and `FieldValueFor` (`domain/schema.ts`) NO LONGER
|
|
90
85
|
* agree element-by-element: `FieldValueFor` is the bare runtime payload
|
|
@@ -100,13 +95,13 @@ type SlotItem<S extends SectionSchema> = {
|
|
|
100
95
|
* "user-extensible field types" — invariant 5 (CLAUDE.md) forbids a
|
|
101
96
|
* plugin system; this is just the internal seam.
|
|
102
97
|
*/
|
|
103
|
-
type FieldDataType<F extends FieldDescriptor> = F extends TextField ? EditableSlot<'text', string> : F extends RichTextField ? EditableSlot<'richText', string> : F extends ImageField ? EditableSlot<'image', ImageValue> : F extends VideoField ? EditableSlot<'video', VideoValue> : F extends ReferenceField ? ReferenceValue : F extends LinkField ? EditableSlot<'link', LinkValue> : F extends ButtonField ? EditableSlot<'button', ButtonValue> : F extends NumberField ? EditableSlot<'number', number> : F extends BooleanField ? EditableSlot<'boolean', boolean> : F extends SelectField ? EditableSlot<'select', string> : F extends ListField<infer S> ? EditableSlot<'list', ReadonlyArray<SlotItem<S>>> :
|
|
98
|
+
type FieldDataType<F extends FieldDescriptor> = F extends TextField ? EditableSlot<'text', string> : F extends RichTextField ? EditableSlot<'richText', string> : F extends ImageField ? EditableSlot<'image', ImageValue> : F extends VideoField ? EditableSlot<'video', VideoValue> : F extends ReferenceField ? ReferenceValue : F extends LinkField ? EditableSlot<'link', LinkValue> : F extends ButtonField ? EditableSlot<'button', ButtonValue> : F extends NumberField ? EditableSlot<'number', number> : F extends BooleanField ? EditableSlot<'boolean', boolean> : F extends SelectField ? EditableSlot<'select', string> : F extends ListField<infer S> ? EditableSlot<'list', ReadonlyArray<SlotItem<S>>> : never;
|
|
104
99
|
/**
|
|
105
100
|
* Derives the SECTION-COMPONENT prop shape from its schema.
|
|
106
101
|
*
|
|
107
102
|
* Per `FieldDataType`, every editable field becomes an `EditableSlot<K,V>`
|
|
108
|
-
* (so `<h1>{title}</h1>` is a TS error); `ReferenceValue`
|
|
109
|
-
*
|
|
103
|
+
* (so `<h1>{title}</h1>` is a TS error); `ReferenceValue` stays raw.
|
|
104
|
+
* Example:
|
|
110
105
|
*
|
|
111
106
|
* type HeroSchema = { title: TextField; image: ImageField; ref: ReferenceField }
|
|
112
107
|
* DataOf<HeroSchema> ≡ {
|
|
@@ -172,16 +167,6 @@ interface SectionDefinition<S extends SectionSchema, C extends SectionComponent<
|
|
|
172
167
|
* never interprets these — consumers that read a specific field narrow
|
|
173
168
|
* at the call site. */
|
|
174
169
|
readonly defaults: Record<string, unknown>;
|
|
175
|
-
/** Optional list of layout names supported by this section. When present
|
|
176
|
-
* with length >= 2, the preview-mode section picker renders a "Layout"
|
|
177
|
-
* tab so authors can switch the layout without editing JSON. The section
|
|
178
|
-
* component reads the active layout from its `layout` prop; the picker
|
|
179
|
-
* writes that value via the existing per-field save round-trip.
|
|
180
|
-
*
|
|
181
|
-
* Layouts are a SECTION-level concern, not a field descriptor, because
|
|
182
|
-
* they gate structure inside a single component rather than introducing
|
|
183
|
-
* a new field type. See ARCHITECTURE.md §4. */
|
|
184
|
-
readonly layouts?: readonly string[];
|
|
185
170
|
}
|
|
186
171
|
/**
|
|
187
172
|
* The erased/heterogeneous form used by the registry and by
|
|
@@ -208,8 +193,6 @@ interface AnySectionDefinition {
|
|
|
208
193
|
readonly component: (props: never) => unknown;
|
|
209
194
|
/** Pre-computed placeholder values — see `SectionDefinition.defaults`. */
|
|
210
195
|
readonly defaults: Record<string, unknown>;
|
|
211
|
-
/** Optional layout names — see `SectionDefinition.layouts`. */
|
|
212
|
-
readonly layouts?: readonly string[];
|
|
213
196
|
}
|
|
214
197
|
/**
|
|
215
198
|
* Input shape for `defineSection`. Split out so the factory can use a single
|
|
@@ -221,8 +204,6 @@ interface DefineSectionInput<S extends SectionSchema, C extends SectionComponent
|
|
|
221
204
|
readonly category?: string;
|
|
222
205
|
readonly schema: S;
|
|
223
206
|
readonly component: C;
|
|
224
|
-
/** Optional layout names — see `SectionDefinition.layouts`. */
|
|
225
|
-
readonly layouts?: readonly string[];
|
|
226
207
|
}
|
|
227
208
|
/**
|
|
228
209
|
* Type-safe factory for a `SectionDefinition`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SectionSchema,
|
|
2
|
-
import { C as ContentStorageAdapter } from './assets-
|
|
1
|
+
import { S as SectionSchema, k as FieldValueFor, j as PageSummary, P as Page } from './page-DXF0_SrY.js';
|
|
2
|
+
import { C as ContentStorageAdapter } from './assets-DHumg-X7.js';
|
|
3
3
|
import { G as Global } from './global-CV23g5Bn.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -194,76 +194,9 @@ interface CreateListPagesDeps {
|
|
|
194
194
|
*/
|
|
195
195
|
declare const createListPages: ({ contentAdapter, }: CreateListPagesDeps) => ListPages;
|
|
196
196
|
|
|
197
|
-
/** Result of a `submitForm` call. */
|
|
198
|
-
type SubmitFormResult = {
|
|
199
|
-
readonly ok: true;
|
|
200
|
-
readonly stored: true;
|
|
201
|
-
readonly id: string;
|
|
202
|
-
} | {
|
|
203
|
-
readonly ok: true;
|
|
204
|
-
readonly stored: false;
|
|
205
|
-
readonly suppressed: 'honeypot';
|
|
206
|
-
} | {
|
|
207
|
-
readonly ok: false;
|
|
208
|
-
readonly error: 'unknown_form';
|
|
209
|
-
} | {
|
|
210
|
-
readonly ok: false;
|
|
211
|
-
readonly error: 'validation_failed';
|
|
212
|
-
readonly errors: Record<string, string>;
|
|
213
|
-
};
|
|
214
|
-
/** Dependencies for `submitForm`. */
|
|
215
|
-
interface SubmitFormDeps {
|
|
216
|
-
/**
|
|
217
|
-
* A `FormLookup`-shaped object: anything with `get(name)` returning a
|
|
218
|
-
* form definition. The concrete `FormRegistry` from `forms/registry.ts`
|
|
219
|
-
* structurally satisfies this interface, so the runtime can stay
|
|
220
|
-
* dependency-free of `forms/` (per ARCHITECTURE.md §8 dep graph).
|
|
221
|
-
*/
|
|
222
|
-
readonly forms: FormLookup;
|
|
223
|
-
readonly submissionAdapter: SubmissionStorageAdapter;
|
|
224
|
-
/** Optional ID generator for tests; defaults to a ULID-like generator. */
|
|
225
|
-
readonly generateId?: () => string;
|
|
226
|
-
/** Optional clock for tests; defaults to `() => new Date().toISOString()`. */
|
|
227
|
-
readonly now?: () => string;
|
|
228
|
-
}
|
|
229
|
-
/** Input to `submitForm`. */
|
|
230
|
-
interface SubmitFormInput {
|
|
231
|
-
readonly formName: string;
|
|
232
|
-
/** The raw payload from the request. Validated here, NOT in the handler. */
|
|
233
|
-
readonly payload: Readonly<Record<string, unknown>>;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Build the runtime function that handles form submissions.
|
|
237
|
-
*
|
|
238
|
-
* Returns a `submitForm(input)` that:
|
|
239
|
-
* 1. Looks up the form definition.
|
|
240
|
-
* 2. Honors honeypot.
|
|
241
|
-
* 3. Validates payload.
|
|
242
|
-
* 4. Stamps id+submittedAt and stores via the adapter.
|
|
243
|
-
*/
|
|
244
|
-
declare function createSubmitForm(deps: SubmitFormDeps): (input: SubmitFormInput) => Promise<SubmitFormResult>;
|
|
245
|
-
/** Type of the function returned by `createSubmitForm`. */
|
|
246
|
-
type SubmitForm = ReturnType<typeof createSubmitForm>;
|
|
247
|
-
|
|
248
197
|
/** Dependencies for the runtime. */
|
|
249
198
|
interface RuntimeOptions {
|
|
250
199
|
readonly contentAdapter: ContentStorageAdapter;
|
|
251
|
-
/**
|
|
252
|
-
* Form registry — required for `submitForm` to look up form definitions.
|
|
253
|
-
* Accepts any `FormLookup`-shaped object (the concrete `FormRegistry`
|
|
254
|
-
* from `forms/registry.ts` satisfies this structurally). Optional for
|
|
255
|
-
* backward compatibility: when omitted, `submitForm` is wired to an
|
|
256
|
-
* empty lookup, so any submission attempt returns `unknown_form`.
|
|
257
|
-
* Templates that use forms (ARCHITECTURE.md §6.5) MUST pass a registry
|
|
258
|
-
* built from `defineConfig({ forms: [...] })`.
|
|
259
|
-
*/
|
|
260
|
-
readonly forms?: FormLookup;
|
|
261
|
-
/**
|
|
262
|
-
* Submission storage adapter. Optional for backward compatibility: when
|
|
263
|
-
* omitted, `submitForm` is wired to a no-op adapter that throws on store.
|
|
264
|
-
* Templates that use forms MUST pass an adapter (FS or webhook).
|
|
265
|
-
*/
|
|
266
|
-
readonly submissionAdapter?: SubmissionStorageAdapter;
|
|
267
200
|
}
|
|
268
201
|
/**
|
|
269
202
|
* The runtime surface returned by `createRuntime`. This is what
|
|
@@ -303,16 +236,6 @@ interface Runtime {
|
|
|
303
236
|
* fall-back branch.
|
|
304
237
|
*/
|
|
305
238
|
readonly getGlobal: GetGlobal;
|
|
306
|
-
/**
|
|
307
|
-
* Accept a form submission. See `runtime/submitForm.ts` for the full
|
|
308
|
-
* pipeline (form lookup, honeypot, validation, store). Rate limiting
|
|
309
|
-
* is handled at the handler layer, not here.
|
|
310
|
-
*
|
|
311
|
-
* When the runtime was built without a `forms` registry or a
|
|
312
|
-
* `submissionAdapter`, `submitForm` returns `{ ok: false, error: 'unknown_form' }`
|
|
313
|
-
* for every call so downstream code can fail closed without crashing.
|
|
314
|
-
*/
|
|
315
|
-
readonly submitForm: SubmitForm;
|
|
316
239
|
/**
|
|
317
240
|
* Return metadata-only summaries of every published page, optionally
|
|
318
241
|
* filtered by a single tag and capped by `limit`. Used by user-defined
|
|
@@ -336,56 +259,4 @@ interface GetContentInput {
|
|
|
336
259
|
*/
|
|
337
260
|
declare function createRuntime(options: RuntimeOptions): Runtime;
|
|
338
261
|
|
|
339
|
-
|
|
340
|
-
interface RateLimitResult {
|
|
341
|
-
/** When `false`, the caller MUST reject the request with HTTP 429. */
|
|
342
|
-
readonly allowed: boolean;
|
|
343
|
-
/** Number of requests counted in the current window after this call. */
|
|
344
|
-
readonly count: number;
|
|
345
|
-
/** Epoch milliseconds when the current window resets. */
|
|
346
|
-
readonly resetAt: number;
|
|
347
|
-
}
|
|
348
|
-
/** Options for `createRateLimit`. */
|
|
349
|
-
interface RateLimitOptions {
|
|
350
|
-
/** Max requests per window per (ip, formName) key. Default: 5. */
|
|
351
|
-
readonly perWindow: number;
|
|
352
|
-
/** Window length in milliseconds. Default: 60_000 (1 minute). */
|
|
353
|
-
readonly windowMs: number;
|
|
354
|
-
/**
|
|
355
|
-
* Clock injection point for tests. Called once per check to read the
|
|
356
|
-
* current time. Defaults to `Date.now`.
|
|
357
|
-
*/
|
|
358
|
-
readonly now?: () => number;
|
|
359
|
-
/**
|
|
360
|
-
* Maximum number of (ip, formName) buckets retained in memory. When
|
|
361
|
-
* the map reaches this size, `check()` lazily sweeps expired buckets;
|
|
362
|
-
* if still at the cap, the oldest-resetAt buckets are dropped to make
|
|
363
|
-
* room. Default: 10_000. Must be a positive integer.
|
|
364
|
-
*
|
|
365
|
-
* Why: a public submit endpoint with one-off IPs (CDN edges, mobile
|
|
366
|
-
* NAT pools, attack traffic) would otherwise grow the map without
|
|
367
|
-
* bound until process restart.
|
|
368
|
-
*/
|
|
369
|
-
readonly maxBuckets?: number;
|
|
370
|
-
}
|
|
371
|
-
interface RateLimit {
|
|
372
|
-
/**
|
|
373
|
-
* Record one request and return whether it is allowed under the current
|
|
374
|
-
* window. Always counts (even rejected calls) — this matches the typical
|
|
375
|
-
* abuse-mitigation expectation: a flood that hits the limit shouldn't
|
|
376
|
-
* "free" itself by spinning down the counter.
|
|
377
|
-
*/
|
|
378
|
-
check(ip: string, formName: string): RateLimitResult;
|
|
379
|
-
/**
|
|
380
|
-
* Test-only utility: clear all buckets. Useful between tests to keep
|
|
381
|
-
* them order-independent without recreating the limiter.
|
|
382
|
-
*/
|
|
383
|
-
reset(): void;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Build an in-memory rate limiter. Each created limiter is independent
|
|
387
|
-
* (no module-level singleton).
|
|
388
|
-
*/
|
|
389
|
-
declare function createRateLimit(options: RateLimitOptions): RateLimit;
|
|
390
|
-
|
|
391
|
-
export { type FieldIn as F, type GetGlobal as G, type ListPages as L, type PreviewMode as P, type RateLimit as R, type SubmitForm as S, type GetContent as a, type GetContentInput as b, type GetContentOptions as c, type GetGlobalInput as d, type ListPagesInput as e, type ListPagesSort as f, type PageContent as g, type PreviewField as h, type PreviewFieldOrigin as i, type RateLimitOptions as j, type RateLimitResult as k, type Runtime as l, type RuntimeOptions as m, type SubmitFormDeps as n, type SubmitFormInput as o, type SubmitFormResult as p, createListPages as q, createRateLimit as r, createRuntime as s, createSubmitForm as t };
|
|
262
|
+
export { type FieldIn as F, type GetGlobal as G, type ListPages as L, type PreviewMode as P, type Runtime as R, type GetContent as a, type GetContentInput as b, type GetContentOptions as c, type GetGlobalInput as d, type ListPagesInput as e, type ListPagesSort as f, type PageContent as g, type PreviewField as h, type PreviewFieldOrigin as i, type RuntimeOptions as j, createListPages as k, createRuntime as l };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SectionSchema,
|
|
2
|
-
import { C as ContentStorageAdapter } from './assets-
|
|
1
|
+
import { S as SectionSchema, k as FieldValueFor, j as PageSummary, P as Page } from './page-DXF0_SrY.cjs';
|
|
2
|
+
import { C as ContentStorageAdapter } from './assets-B3oNeLdj.cjs';
|
|
3
3
|
import { G as Global } from './global-CV23g5Bn.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -194,76 +194,9 @@ interface CreateListPagesDeps {
|
|
|
194
194
|
*/
|
|
195
195
|
declare const createListPages: ({ contentAdapter, }: CreateListPagesDeps) => ListPages;
|
|
196
196
|
|
|
197
|
-
/** Result of a `submitForm` call. */
|
|
198
|
-
type SubmitFormResult = {
|
|
199
|
-
readonly ok: true;
|
|
200
|
-
readonly stored: true;
|
|
201
|
-
readonly id: string;
|
|
202
|
-
} | {
|
|
203
|
-
readonly ok: true;
|
|
204
|
-
readonly stored: false;
|
|
205
|
-
readonly suppressed: 'honeypot';
|
|
206
|
-
} | {
|
|
207
|
-
readonly ok: false;
|
|
208
|
-
readonly error: 'unknown_form';
|
|
209
|
-
} | {
|
|
210
|
-
readonly ok: false;
|
|
211
|
-
readonly error: 'validation_failed';
|
|
212
|
-
readonly errors: Record<string, string>;
|
|
213
|
-
};
|
|
214
|
-
/** Dependencies for `submitForm`. */
|
|
215
|
-
interface SubmitFormDeps {
|
|
216
|
-
/**
|
|
217
|
-
* A `FormLookup`-shaped object: anything with `get(name)` returning a
|
|
218
|
-
* form definition. The concrete `FormRegistry` from `forms/registry.ts`
|
|
219
|
-
* structurally satisfies this interface, so the runtime can stay
|
|
220
|
-
* dependency-free of `forms/` (per ARCHITECTURE.md §8 dep graph).
|
|
221
|
-
*/
|
|
222
|
-
readonly forms: FormLookup;
|
|
223
|
-
readonly submissionAdapter: SubmissionStorageAdapter;
|
|
224
|
-
/** Optional ID generator for tests; defaults to a ULID-like generator. */
|
|
225
|
-
readonly generateId?: () => string;
|
|
226
|
-
/** Optional clock for tests; defaults to `() => new Date().toISOString()`. */
|
|
227
|
-
readonly now?: () => string;
|
|
228
|
-
}
|
|
229
|
-
/** Input to `submitForm`. */
|
|
230
|
-
interface SubmitFormInput {
|
|
231
|
-
readonly formName: string;
|
|
232
|
-
/** The raw payload from the request. Validated here, NOT in the handler. */
|
|
233
|
-
readonly payload: Readonly<Record<string, unknown>>;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Build the runtime function that handles form submissions.
|
|
237
|
-
*
|
|
238
|
-
* Returns a `submitForm(input)` that:
|
|
239
|
-
* 1. Looks up the form definition.
|
|
240
|
-
* 2. Honors honeypot.
|
|
241
|
-
* 3. Validates payload.
|
|
242
|
-
* 4. Stamps id+submittedAt and stores via the adapter.
|
|
243
|
-
*/
|
|
244
|
-
declare function createSubmitForm(deps: SubmitFormDeps): (input: SubmitFormInput) => Promise<SubmitFormResult>;
|
|
245
|
-
/** Type of the function returned by `createSubmitForm`. */
|
|
246
|
-
type SubmitForm = ReturnType<typeof createSubmitForm>;
|
|
247
|
-
|
|
248
197
|
/** Dependencies for the runtime. */
|
|
249
198
|
interface RuntimeOptions {
|
|
250
199
|
readonly contentAdapter: ContentStorageAdapter;
|
|
251
|
-
/**
|
|
252
|
-
* Form registry — required for `submitForm` to look up form definitions.
|
|
253
|
-
* Accepts any `FormLookup`-shaped object (the concrete `FormRegistry`
|
|
254
|
-
* from `forms/registry.ts` satisfies this structurally). Optional for
|
|
255
|
-
* backward compatibility: when omitted, `submitForm` is wired to an
|
|
256
|
-
* empty lookup, so any submission attempt returns `unknown_form`.
|
|
257
|
-
* Templates that use forms (ARCHITECTURE.md §6.5) MUST pass a registry
|
|
258
|
-
* built from `defineConfig({ forms: [...] })`.
|
|
259
|
-
*/
|
|
260
|
-
readonly forms?: FormLookup;
|
|
261
|
-
/**
|
|
262
|
-
* Submission storage adapter. Optional for backward compatibility: when
|
|
263
|
-
* omitted, `submitForm` is wired to a no-op adapter that throws on store.
|
|
264
|
-
* Templates that use forms MUST pass an adapter (FS or webhook).
|
|
265
|
-
*/
|
|
266
|
-
readonly submissionAdapter?: SubmissionStorageAdapter;
|
|
267
200
|
}
|
|
268
201
|
/**
|
|
269
202
|
* The runtime surface returned by `createRuntime`. This is what
|
|
@@ -303,16 +236,6 @@ interface Runtime {
|
|
|
303
236
|
* fall-back branch.
|
|
304
237
|
*/
|
|
305
238
|
readonly getGlobal: GetGlobal;
|
|
306
|
-
/**
|
|
307
|
-
* Accept a form submission. See `runtime/submitForm.ts` for the full
|
|
308
|
-
* pipeline (form lookup, honeypot, validation, store). Rate limiting
|
|
309
|
-
* is handled at the handler layer, not here.
|
|
310
|
-
*
|
|
311
|
-
* When the runtime was built without a `forms` registry or a
|
|
312
|
-
* `submissionAdapter`, `submitForm` returns `{ ok: false, error: 'unknown_form' }`
|
|
313
|
-
* for every call so downstream code can fail closed without crashing.
|
|
314
|
-
*/
|
|
315
|
-
readonly submitForm: SubmitForm;
|
|
316
239
|
/**
|
|
317
240
|
* Return metadata-only summaries of every published page, optionally
|
|
318
241
|
* filtered by a single tag and capped by `limit`. Used by user-defined
|
|
@@ -336,56 +259,4 @@ interface GetContentInput {
|
|
|
336
259
|
*/
|
|
337
260
|
declare function createRuntime(options: RuntimeOptions): Runtime;
|
|
338
261
|
|
|
339
|
-
|
|
340
|
-
interface RateLimitResult {
|
|
341
|
-
/** When `false`, the caller MUST reject the request with HTTP 429. */
|
|
342
|
-
readonly allowed: boolean;
|
|
343
|
-
/** Number of requests counted in the current window after this call. */
|
|
344
|
-
readonly count: number;
|
|
345
|
-
/** Epoch milliseconds when the current window resets. */
|
|
346
|
-
readonly resetAt: number;
|
|
347
|
-
}
|
|
348
|
-
/** Options for `createRateLimit`. */
|
|
349
|
-
interface RateLimitOptions {
|
|
350
|
-
/** Max requests per window per (ip, formName) key. Default: 5. */
|
|
351
|
-
readonly perWindow: number;
|
|
352
|
-
/** Window length in milliseconds. Default: 60_000 (1 minute). */
|
|
353
|
-
readonly windowMs: number;
|
|
354
|
-
/**
|
|
355
|
-
* Clock injection point for tests. Called once per check to read the
|
|
356
|
-
* current time. Defaults to `Date.now`.
|
|
357
|
-
*/
|
|
358
|
-
readonly now?: () => number;
|
|
359
|
-
/**
|
|
360
|
-
* Maximum number of (ip, formName) buckets retained in memory. When
|
|
361
|
-
* the map reaches this size, `check()` lazily sweeps expired buckets;
|
|
362
|
-
* if still at the cap, the oldest-resetAt buckets are dropped to make
|
|
363
|
-
* room. Default: 10_000. Must be a positive integer.
|
|
364
|
-
*
|
|
365
|
-
* Why: a public submit endpoint with one-off IPs (CDN edges, mobile
|
|
366
|
-
* NAT pools, attack traffic) would otherwise grow the map without
|
|
367
|
-
* bound until process restart.
|
|
368
|
-
*/
|
|
369
|
-
readonly maxBuckets?: number;
|
|
370
|
-
}
|
|
371
|
-
interface RateLimit {
|
|
372
|
-
/**
|
|
373
|
-
* Record one request and return whether it is allowed under the current
|
|
374
|
-
* window. Always counts (even rejected calls) — this matches the typical
|
|
375
|
-
* abuse-mitigation expectation: a flood that hits the limit shouldn't
|
|
376
|
-
* "free" itself by spinning down the counter.
|
|
377
|
-
*/
|
|
378
|
-
check(ip: string, formName: string): RateLimitResult;
|
|
379
|
-
/**
|
|
380
|
-
* Test-only utility: clear all buckets. Useful between tests to keep
|
|
381
|
-
* them order-independent without recreating the limiter.
|
|
382
|
-
*/
|
|
383
|
-
reset(): void;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Build an in-memory rate limiter. Each created limiter is independent
|
|
387
|
-
* (no module-level singleton).
|
|
388
|
-
*/
|
|
389
|
-
declare function createRateLimit(options: RateLimitOptions): RateLimit;
|
|
390
|
-
|
|
391
|
-
export { type FieldIn as F, type GetGlobal as G, type ListPages as L, type PreviewMode as P, type RateLimit as R, type SubmitForm as S, type GetContent as a, type GetContentInput as b, type GetContentOptions as c, type GetGlobalInput as d, type ListPagesInput as e, type ListPagesSort as f, type PageContent as g, type PreviewField as h, type PreviewFieldOrigin as i, type RateLimitOptions as j, type RateLimitResult as k, type Runtime as l, type RuntimeOptions as m, type SubmitFormDeps as n, type SubmitFormInput as o, type SubmitFormResult as p, createListPages as q, createRateLimit as r, createRuntime as s, createSubmitForm as t };
|
|
262
|
+
export { type FieldIn as F, type GetGlobal as G, type ListPages as L, type PreviewMode as P, type Runtime as R, type GetContent as a, type GetContentInput as b, type GetContentOptions as c, type GetGlobalInput as d, type ListPagesInput as e, type ListPagesSort as f, type PageContent as g, type PreviewField as h, type PreviewFieldOrigin as i, type RuntimeOptions as j, createListPages as k, createRuntime as l };
|