@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.
@@ -1,6 +1,6 @@
1
- import { C as ContentStorageAdapter, A as AssetStorageAdapter } from './assets-P8OCigDG.js';
2
- import { l as Runtime, R as RateLimit } from './rateLimit-CXptRM_K.js';
3
- import { A as AnyFormDefinition, o as SubmissionStorageAdapter } from './form-BqY0H1V5.js';
1
+ import { C as ContentStorageAdapter, A as AssetStorageAdapter } from './assets-DHumg-X7.js';
2
+ import { R as Runtime } from './getContent-DAgAn095.js';
3
+ import './page-DXF0_SrY.js';
4
4
  import './global-CV23g5Bn.js';
5
5
 
6
6
  type TaskId = string;
@@ -261,72 +261,6 @@ interface GlobalHandler {
261
261
  }
262
262
  declare function createGlobalHandler(deps: GlobalHandlerDeps): GlobalHandler;
263
263
 
264
- /**
265
- * Template definition shape matching `PageTemplate` from config.
266
- * Redeclared here as a structural type so the handler does not import
267
- * from config/ (invariant 1).
268
- */
269
- interface TemplateDef {
270
- readonly name: string;
271
- readonly description?: string;
272
- readonly sectionTypes: readonly string[];
273
- }
274
- interface TemplateHandlerDeps {
275
- /**
276
- * Pre-resolved map: section type name -> default data for that section.
277
- * Built by the wiring layer from the registered `AnySectionDefinition[]`.
278
- */
279
- readonly sectionDefaults: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
280
- /** The template definitions from config. */
281
- readonly templates: readonly TemplateDef[];
282
- }
283
- interface TemplateHandler {
284
- /** GET /api/agntcms/template/list */
285
- readonly list: (req: Request) => Promise<Response>;
286
- }
287
- declare function createTemplateHandler(deps: TemplateHandlerDeps): TemplateHandler;
288
-
289
- interface SubmitHandlerDeps {
290
- readonly runtime: Runtime;
291
- readonly rateLimit: RateLimit;
292
- }
293
- declare function createSubmitFormHandler(deps: SubmitHandlerDeps): (req: Request) => Promise<Response>;
294
-
295
- /**
296
- * Adapter info surfaced to the AdminModal. Two shapes:
297
- * - `{ kind: 'fs' }` — local FS submissions; readable.
298
- * - `{ kind: 'webhook', host }` — webhook adapter; not locally readable.
299
- */
300
- type FormsListAdapterInfo = {
301
- readonly kind: 'fs';
302
- } | {
303
- readonly kind: 'webhook';
304
- readonly host: string;
305
- };
306
- interface FormsListHandlerDeps {
307
- /** Registered form definitions (from `defineConfig({ forms: [...] })`). */
308
- readonly forms: ReadonlyArray<AnyFormDefinition>;
309
- /**
310
- * Optional adapter descriptor. When omitted, the handler reports
311
- * `{ kind: 'fs' }` — the v1 default adapter (ARCHITECTURE.md §6.5).
312
- * Frozen routes that wire a webhook adapter pass `{ kind: 'webhook',
313
- * host: '<host>' }` here; the host is computed once at handler-construction
314
- * time from the configured webhook URL.
315
- */
316
- readonly adapter?: FormsListAdapterInfo;
317
- }
318
- /** Forms list handler. */
319
- declare function createFormsListHandler(deps: FormsListHandlerDeps): (_req: Request) => Promise<Response>;
320
-
321
- interface FormsReadHandlerDeps {
322
- readonly submissionAdapter: SubmissionStorageAdapter;
323
- /** Registered form names — used to 404 unknown forms before hitting the adapter. */
324
- readonly knownForms: ReadonlySet<string>;
325
- }
326
- declare function createFormsReadHandler(deps: FormsReadHandlerDeps): (req: Request) => Promise<Response>;
327
-
328
- declare function createFormsDeleteHandler(): (_req: Request) => Promise<Response>;
329
-
330
264
  /**
331
265
  * Dependencies for every endpoint the dispatcher serves. Grouped by
332
266
  * underlying handler factory so the template wiring mirrors the v0.2
@@ -346,9 +280,6 @@ interface agntcmsRouteHandlerOptions {
346
280
  readonly preview?: PreviewHandlerDeps;
347
281
  readonly events: EventsHandlerDeps;
348
282
  readonly mcp: McpHandlerDeps;
349
- readonly template: TemplateHandlerDeps;
350
- readonly formsList: FormsListHandlerDeps;
351
- readonly formsRead: FormsReadHandlerDeps;
352
283
  }
353
284
  /** HTTP methods the dispatcher routes. */
354
285
  type DispatcherMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
@@ -391,4 +322,4 @@ interface agntcmsRouteHandler {
391
322
  */
392
323
  declare function createagntcmsRouteHandler(opts: agntcmsRouteHandlerOptions): agntcmsRouteHandler;
393
324
 
394
- export { type AgentBridge, type AgentBridgeStatus, AgentUnreachableError, type AssetsHandler, type AssetsHandlerDeps, type CreateAgentBridgeOptions, type DispatcherMethod, type DraftHandler, type DraftHandlerDeps, type EventsHandler, type EventsHandlerDeps, type FormsListAdapterInfo, type FormsListHandlerDeps, type FormsReadHandlerDeps, type GlobalHandler, type GlobalHandlerDeps, type McpHandler, type McpHandlerDeps, type PageHandler, type PageHandlerDeps, type PreviewHandler, type PreviewHandlerDeps, type PreviewToken, type PreviewTokenStore, type PreviewTokenStoreOptions, type SubmitHandlerDeps, type Task, type TaskEvent, type TaskId, type TaskSnapshot, type TaskState, type TaskStore, type TemplateHandler, type TemplateHandlerDeps, type agntcmsRouteContext, type agntcmsRouteHandler, type agntcmsRouteHandlerOptions, createAgentBridge, createAssetsHandler, createDraftHandler, createEventsHandler, createFormsDeleteHandler, createFormsListHandler, createFormsReadHandler, createGlobalHandler, createMcpHandler, createPageHandler, createPreviewHandler, createPreviewTokenStore, createSubmitFormHandler, createTaskStore, createTemplateHandler, createagntcmsRouteHandler };
325
+ export { type AgentBridge, type AgentBridgeStatus, AgentUnreachableError, type AssetsHandler, type AssetsHandlerDeps, type CreateAgentBridgeOptions, type DispatcherMethod, type DraftHandler, type DraftHandlerDeps, type EventsHandler, type EventsHandlerDeps, type GlobalHandler, type GlobalHandlerDeps, type McpHandler, type McpHandlerDeps, type PageHandler, type PageHandlerDeps, type PreviewHandler, type PreviewHandlerDeps, type PreviewToken, type PreviewTokenStore, type PreviewTokenStoreOptions, type Task, type TaskEvent, type TaskId, type TaskSnapshot, type TaskState, type TaskStore, type agntcmsRouteContext, type agntcmsRouteHandler, type agntcmsRouteHandlerOptions, createAgentBridge, createAssetsHandler, createDraftHandler, createEventsHandler, createGlobalHandler, createMcpHandler, createPageHandler, createPreviewHandler, createPreviewTokenStore, createTaskStore, createagntcmsRouteHandler };
package/dist/handlers.mjs CHANGED
@@ -182,14 +182,6 @@ function assertValidPage(page) {
182
182
  assertValidPageMeta(obj);
183
183
  }
184
184
 
185
- // src/domain/form.ts
186
- var SubmissionsNotReadableError = class extends Error {
187
- constructor(message = "submission adapter does not support reading") {
188
- super(message);
189
- this.name = "SubmissionsNotReadableError";
190
- }
191
- };
192
-
193
185
  // src/storage/fs/content.ts
194
186
  var SLUG_PATTERN = /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/;
195
187
  var assertValidSlug = (slug) => {
@@ -250,7 +242,7 @@ var createFsContentAdapter = (options) => {
250
242
  throw err;
251
243
  }
252
244
  };
253
- const listJsonFiles2 = async (dir) => {
245
+ const listJsonFiles = async (dir) => {
254
246
  let entries;
255
247
  try {
256
248
  entries = await fs3.readdir(dir, { withFileTypes: true });
@@ -264,7 +256,7 @@ var createFsContentAdapter = (options) => {
264
256
  results.push(entry.name);
265
257
  } else if (entry.isDirectory()) {
266
258
  const subDir = path3.join(dir, entry.name);
267
- const subFiles = await listJsonFiles2(subDir);
259
+ const subFiles = await listJsonFiles(subDir);
268
260
  for (const sub of subFiles) {
269
261
  results.push(`${entry.name}/${sub}`);
270
262
  }
@@ -303,7 +295,7 @@ var createFsContentAdapter = (options) => {
303
295
  await writeAtomic(filePath, JSON.stringify(page, null, 2));
304
296
  };
305
297
  const listDrafts = async () => {
306
- const files = await listJsonFiles2(draftsDir);
298
+ const files = await listJsonFiles(draftsDir);
307
299
  const results = [];
308
300
  for (const relPath of files) {
309
301
  const slug = relPath.slice(0, -".json".length);
@@ -313,7 +305,7 @@ var createFsContentAdapter = (options) => {
313
305
  return results;
314
306
  };
315
307
  const listPages = async () => {
316
- const files = await listJsonFiles2(pagesDir);
308
+ const files = await listJsonFiles(pagesDir);
317
309
  const results = [];
318
310
  for (const relPath of files) {
319
311
  const slug = relPath.slice(0, -".json".length);
@@ -323,7 +315,7 @@ var createFsContentAdapter = (options) => {
323
315
  return results;
324
316
  };
325
317
  const listPageSummaries = async () => {
326
- const files = await listJsonFiles2(pagesDir);
318
+ const files = await listJsonFiles(pagesDir);
327
319
  const results = [];
328
320
  for (const relPath of files) {
329
321
  const slug = relPath.slice(0, -".json".length);
@@ -621,151 +613,6 @@ var createFsContentAdapter = (options) => {
621
613
  };
622
614
  };
623
615
 
624
- // src/storage/fs/submissions.ts
625
- import { randomUUID } from "crypto";
626
- import * as fs4 from "fs/promises";
627
- import * as path4 from "path";
628
- var DEFAULT_MAX_LIST = 500;
629
- var FORM_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
630
- var parseSubmission = (raw) => {
631
- let parsed;
632
- try {
633
- parsed = JSON.parse(raw);
634
- } catch {
635
- return null;
636
- }
637
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
638
- return null;
639
- }
640
- const obj = parsed;
641
- if (typeof obj["formName"] !== "string") return null;
642
- if (typeof obj["id"] !== "string") return null;
643
- if (typeof obj["submittedAt"] !== "string") return null;
644
- if (obj["payload"] === null || typeof obj["payload"] !== "object" || Array.isArray(obj["payload"])) {
645
- return null;
646
- }
647
- return {
648
- formName: obj["formName"],
649
- id: obj["id"],
650
- submittedAt: obj["submittedAt"],
651
- payload: obj["payload"]
652
- };
653
- };
654
- var assertValidFormName = (name) => {
655
- if (typeof name !== "string" || !FORM_NAME_PATTERN.test(name)) {
656
- throw new Error(`invalid form name: ${JSON.stringify(name)}`);
657
- }
658
- };
659
- var submissionFilename = (submittedAt, id) => {
660
- const ts = submittedAt.replace(/:/g, "-");
661
- return `${ts}-${id}.json`;
662
- };
663
- var listJsonFiles = async (dir) => {
664
- let entries;
665
- try {
666
- entries = await fs4.readdir(dir, { withFileTypes: true });
667
- } catch (err) {
668
- if (isEnoent(err)) return [];
669
- throw err;
670
- }
671
- const results = [];
672
- for (const entry of entries) {
673
- if (entry.isFile() && entry.name.endsWith(".json")) {
674
- results.push(entry.name);
675
- }
676
- }
677
- return results;
678
- };
679
- var createFsSubmissionAdapter = (options) => {
680
- const { submissionsRoot } = options;
681
- if (!path4.isAbsolute(submissionsRoot)) {
682
- throw new Error(
683
- `submissionsRoot must be an absolute path, got: ${JSON.stringify(submissionsRoot)}`
684
- );
685
- }
686
- const maxList = options.maxList ?? DEFAULT_MAX_LIST;
687
- if (!Number.isFinite(maxList) || maxList <= 0 || !Number.isInteger(maxList)) {
688
- throw new Error(
689
- `maxList must be a positive integer, got: ${maxList}`
690
- );
691
- }
692
- const rootResolved = path4.resolve(submissionsRoot);
693
- const rootWithSep = rootResolved.endsWith(path4.sep) ? rootResolved : rootResolved + path4.sep;
694
- const formDir = (formName) => {
695
- assertValidFormName(formName);
696
- const dir = path4.resolve(rootResolved, formName);
697
- if (!dir.startsWith(rootWithSep)) {
698
- throw new Error(`form name escapes submissions root: ${JSON.stringify(formName)}`);
699
- }
700
- return dir;
701
- };
702
- const cryptoSuffix = () => randomUUID();
703
- const store = async (submission) => {
704
- const dir = formDir(submission.formName);
705
- const filename = submissionFilename(submission.submittedAt, submission.id);
706
- if (filename.includes("/") || filename.includes("\\")) {
707
- throw new Error(`submission id contains path separator: ${JSON.stringify(submission.id)}`);
708
- }
709
- const target = path4.join(dir, filename);
710
- await writeAtomic(target, JSON.stringify(submission, null, 2), cryptoSuffix);
711
- };
712
- const list = async (formName) => {
713
- const dir = formDir(formName);
714
- const files = await listJsonFiles(dir);
715
- const summaries = [];
716
- for (const filename of files) {
717
- const stem = filename.slice(0, -".json".length);
718
- const lastDash = stem.lastIndexOf("-");
719
- if (lastDash < 0) continue;
720
- const tsRaw = stem.slice(0, lastDash);
721
- const id = stem.slice(lastDash + 1);
722
- if (id === "") continue;
723
- const tIndex = tsRaw.indexOf("T");
724
- if (tIndex < 0) continue;
725
- const datePart = tsRaw.slice(0, tIndex);
726
- const timePart = tsRaw.slice(tIndex + 1).replace(/-/g, ":");
727
- const submittedAt = `${datePart}T${timePart}`;
728
- summaries.push({ id, submittedAt });
729
- }
730
- summaries.sort((a, b) => {
731
- if (a.submittedAt !== b.submittedAt) {
732
- return a.submittedAt < b.submittedAt ? 1 : -1;
733
- }
734
- if (a.id !== b.id) {
735
- return a.id < b.id ? 1 : -1;
736
- }
737
- return 0;
738
- });
739
- return summaries.length > maxList ? summaries.slice(0, maxList) : summaries;
740
- };
741
- const read = async (formName, id) => {
742
- if (id.includes("/") || id.includes("\\") || id.includes("..")) {
743
- return null;
744
- }
745
- const dir = formDir(formName);
746
- let entries;
747
- try {
748
- entries = (await fs4.readdir(dir)).filter((n) => n.endsWith(".json"));
749
- } catch (err) {
750
- if (isEnoent(err)) return null;
751
- throw err;
752
- }
753
- const suffix = `-${id}.json`;
754
- const found = entries.find((n) => n.endsWith(suffix));
755
- if (!found) return null;
756
- const target = path4.join(dir, found);
757
- let raw;
758
- try {
759
- raw = await fs4.readFile(target, { encoding: "utf8" });
760
- } catch (err) {
761
- if (isEnoent(err)) return null;
762
- throw err;
763
- }
764
- return parseSubmission(raw);
765
- };
766
- return { info: { kind: "fs" }, store, list, read };
767
- };
768
-
769
616
  // src/config/defaults-registry.ts
770
617
  var SLOT = /* @__PURE__ */ Symbol.for("@agntcms/next/default-adapter-factories");
771
618
  function holder() {
@@ -776,31 +623,24 @@ function registerDefaultAdapterFactories(factories) {
776
623
  }
777
624
 
778
625
  // src/config/defaults.ts
779
- import * as path5 from "path";
626
+ import * as path4 from "path";
780
627
  function createDefaultContentAdapter(options) {
781
628
  const root = options?.projectRoot ?? process.cwd();
782
629
  return createFsContentAdapter({
783
- contentRoot: path5.resolve(root, "content")
630
+ contentRoot: path4.resolve(root, "content")
784
631
  });
785
632
  }
786
633
  function createDefaultAssetAdapter(options) {
787
634
  const root = options?.projectRoot ?? process.cwd();
788
635
  return createFsAssetAdapter({
789
- assetsRoot: path5.resolve(root, "public/assets"),
636
+ assetsRoot: path4.resolve(root, "public/assets"),
790
637
  publicUrlBase: "/assets"
791
638
  });
792
639
  }
793
- function createDefaultSubmissionAdapter(options) {
794
- const root = options?.projectRoot ?? process.cwd();
795
- return createFsSubmissionAdapter({
796
- submissionsRoot: path5.resolve(root, "content/submissions")
797
- });
798
- }
799
640
  function installDefaultAdapterFactories() {
800
641
  const factories = {
801
642
  content: createDefaultContentAdapter,
802
- asset: createDefaultAssetAdapter,
803
- submission: createDefaultSubmissionAdapter
643
+ asset: createDefaultAssetAdapter
804
644
  };
805
645
  registerDefaultAdapterFactories(factories);
806
646
  }
@@ -1601,11 +1441,11 @@ var createTaskStore = () => {
1601
1441
  if (entries.has(task.id)) {
1602
1442
  throw new Error(`duplicate task id: ${task.id}`);
1603
1443
  }
1604
- return new Promise((resolve6, reject) => {
1444
+ return new Promise((resolve5, reject) => {
1605
1445
  const entry = {
1606
1446
  state: "pending",
1607
1447
  task,
1608
- resolve: resolve6,
1448
+ resolve: resolve5,
1609
1449
  reject,
1610
1450
  listeners: /* @__PURE__ */ new Set()
1611
1451
  };
@@ -1669,7 +1509,7 @@ var createTaskStore = () => {
1669
1509
  };
1670
1510
 
1671
1511
  // src/preview-tokens/store.ts
1672
- import { randomUUID as randomUUID2 } from "crypto";
1512
+ import { randomUUID } from "crypto";
1673
1513
  var DEFAULT_TTL_MS = 6e5;
1674
1514
  var createPreviewTokenStore = (options) => {
1675
1515
  const ttlMs = options?.ttlMs ?? DEFAULT_TTL_MS;
@@ -1684,7 +1524,7 @@ var createPreviewTokenStore = (options) => {
1684
1524
  const issue = (slug) => {
1685
1525
  const now = Date.now();
1686
1526
  sweep(now);
1687
- const token = randomUUID2();
1527
+ const token = randomUUID();
1688
1528
  const entry = { slug, createdAt: now };
1689
1529
  entries.set(token, entry);
1690
1530
  return { token, slug, createdAt: now };
@@ -1705,7 +1545,7 @@ var createPreviewTokenStore = (options) => {
1705
1545
  };
1706
1546
 
1707
1547
  // src/handlers/page/page-handler.ts
1708
- import { randomUUID as randomUUID3 } from "crypto";
1548
+ import { randomUUID as randomUUID2 } from "crypto";
1709
1549
  var SLUG_PATTERN2 = /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/;
1710
1550
  var reservedSlugResponse = (slug, error) => {
1711
1551
  const violation = getReservedPageSlugViolation(slug);
@@ -1714,7 +1554,7 @@ var reservedSlugResponse = (slug, error) => {
1714
1554
  };
1715
1555
  var cloneSection = (section) => {
1716
1556
  const fresh = {
1717
- id: `sec_${randomUUID3()}`,
1557
+ id: `sec_${randomUUID2()}`,
1718
1558
  type: section.type,
1719
1559
  data: section.data,
1720
1560
  ...section.globalRef !== void 0 ? { globalRef: section.globalRef } : {}
@@ -2266,191 +2106,6 @@ function createGlobalHandler(deps) {
2266
2106
  return { list, read, save, delete: deleteHandler, listHistory, rollback };
2267
2107
  }
2268
2108
 
2269
- // src/handlers/template/template-handler.ts
2270
- function createTemplateHandler(deps) {
2271
- const { sectionDefaults, templates } = deps;
2272
- const list = async (_req) => {
2273
- const resolved = [];
2274
- for (const template of templates) {
2275
- const sections = [];
2276
- for (const typeName of template.sectionTypes) {
2277
- const defaults = sectionDefaults.get(typeName);
2278
- if (!defaults) {
2279
- console.warn(
2280
- `[agntcms] Template "${template.name}": section type "${typeName}" not found in registered sections, skipping.`
2281
- );
2282
- continue;
2283
- }
2284
- sections.push({ type: typeName, data: defaults });
2285
- }
2286
- resolved.push({
2287
- name: template.name,
2288
- ...template.description !== void 0 ? { description: template.description } : {},
2289
- sections
2290
- });
2291
- }
2292
- return jsonResponse({ templates: resolved }, 200);
2293
- };
2294
- return { list };
2295
- }
2296
-
2297
- // src/handlers/forms/submit-handler.ts
2298
- var extractIp = (req) => {
2299
- const xff = req.headers.get("x-forwarded-for");
2300
- if (xff) {
2301
- const first = xff.split(",")[0]?.trim();
2302
- if (first && first.length > 0) return first;
2303
- }
2304
- const xri = req.headers.get("x-real-ip");
2305
- if (xri && xri.trim().length > 0) return xri.trim();
2306
- return "unknown";
2307
- };
2308
- function createSubmitFormHandler(deps) {
2309
- const { runtime, rateLimit } = deps;
2310
- return async function handle(req) {
2311
- let body;
2312
- try {
2313
- body = await req.json();
2314
- } catch {
2315
- return jsonResponse({ ok: false, error: "invalid_json" }, 400);
2316
- }
2317
- if (body === null || typeof body !== "object") {
2318
- return jsonResponse({ ok: false, error: "invalid_body" }, 400);
2319
- }
2320
- const obj = body;
2321
- if (typeof obj["formName"] !== "string" || obj["formName"] === "") {
2322
- return jsonResponse({ ok: false, error: "missing_form_name" }, 400);
2323
- }
2324
- const payload = obj["payload"];
2325
- if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
2326
- return jsonResponse({ ok: false, error: "invalid_payload" }, 400);
2327
- }
2328
- const formName = obj["formName"];
2329
- const ip = extractIp(req);
2330
- const rl = rateLimit.check(ip, formName);
2331
- if (!rl.allowed) {
2332
- return jsonResponse({ ok: false, error: "rate_limit" }, 429, {
2333
- // Inform polite clients when they may retry. Spec-compliant for 429.
2334
- "Retry-After": Math.max(1, Math.ceil((rl.resetAt - Date.now()) / 1e3)).toString()
2335
- });
2336
- }
2337
- let result;
2338
- try {
2339
- result = await runtime.submitForm({
2340
- formName,
2341
- payload
2342
- });
2343
- } catch (err) {
2344
- void safeErrorMessage(err);
2345
- return jsonResponse({ ok: false, error: "storage_unavailable" }, 502);
2346
- }
2347
- if (!result.ok) {
2348
- switch (result.error) {
2349
- case "unknown_form":
2350
- return jsonResponse({ ok: false, error: "unknown_form" }, 404);
2351
- case "validation_failed":
2352
- return jsonResponse(
2353
- { ok: false, error: "validation_failed", errors: result.errors },
2354
- 400
2355
- );
2356
- default: {
2357
- const _exhaustive = result;
2358
- void _exhaustive;
2359
- return jsonResponse({ ok: false, error: "internal_error" }, 500);
2360
- }
2361
- }
2362
- }
2363
- if (!result.stored) {
2364
- return jsonResponse({ ok: true, stored: false }, 200);
2365
- }
2366
- return jsonResponse({ ok: true, stored: true, id: result.id }, 200);
2367
- };
2368
- }
2369
-
2370
- // src/handlers/forms/list-handler.ts
2371
- function createFormsListHandler(deps) {
2372
- const adapter = deps.adapter ?? { kind: "fs" };
2373
- return async function handle(_req) {
2374
- try {
2375
- const forms = deps.forms.map((f) => {
2376
- const schema = {};
2377
- for (const [name, descriptor] of Object.entries(f.schema)) {
2378
- schema[name] = descriptor;
2379
- }
2380
- return { name: f.name, schema };
2381
- });
2382
- return jsonResponse({ forms, adapter }, 200);
2383
- } catch (err) {
2384
- console.error("[agntcms] list_forms_failed:", err);
2385
- return jsonResponse({ error: "list_forms_failed", message: "internal error" }, 500);
2386
- }
2387
- };
2388
- }
2389
-
2390
- // src/handlers/forms/read-handler.ts
2391
- var FORM_NAME_PATTERN2 = /^[a-zA-Z0-9_-]+$/;
2392
- var ID_PATTERN = /^[0-9A-HJKMNPQRSTVWXYZ]{16}$/;
2393
- function createFormsReadHandler(deps) {
2394
- return async function handle(req) {
2395
- const url = new URL(req.url);
2396
- const form = url.searchParams.get("form");
2397
- const id = url.searchParams.get("id");
2398
- if (!form) return jsonResponse({ error: "missing_form" }, 400);
2399
- if (!FORM_NAME_PATTERN2.test(form)) {
2400
- return jsonResponse({ error: "invalid_form" }, 400);
2401
- }
2402
- if (!deps.knownForms.has(form)) {
2403
- return jsonResponse({ error: "unknown_form" }, 404);
2404
- }
2405
- if (id !== null) {
2406
- if (!ID_PATTERN.test(id)) {
2407
- return jsonResponse({ error: "invalid_id" }, 400);
2408
- }
2409
- try {
2410
- const sub = await deps.submissionAdapter.read(form, id);
2411
- if (!sub) return jsonResponse({ error: "not_found" }, 404);
2412
- return jsonResponse({ submission: sub }, 200);
2413
- } catch (err) {
2414
- if (err instanceof SubmissionsNotReadableError) {
2415
- return jsonResponse(
2416
- { error: "not_supported", message: err.message },
2417
- 501
2418
- );
2419
- }
2420
- console.error("[agntcms] read_failed:", err);
2421
- return jsonResponse({ error: "read_failed", message: "internal error" }, 500);
2422
- }
2423
- }
2424
- try {
2425
- const summaries = await deps.submissionAdapter.list(form);
2426
- return jsonResponse({ submissions: summaries }, 200);
2427
- } catch (err) {
2428
- if (err instanceof SubmissionsNotReadableError) {
2429
- return jsonResponse(
2430
- { error: "not_supported", message: err.message },
2431
- 501
2432
- );
2433
- }
2434
- console.error("[agntcms] list_failed:", err);
2435
- return jsonResponse({ error: "list_failed", message: "internal error" }, 500);
2436
- }
2437
- };
2438
- }
2439
-
2440
- // src/handlers/forms/delete-handler.ts
2441
- function createFormsDeleteHandler() {
2442
- return async function handle(_req) {
2443
- return jsonResponse(
2444
- {
2445
- ok: false,
2446
- error: "not_implemented",
2447
- message: "Submission delete is reserved but not implemented in v1. See ARCHITECTURE.md \xA76.5 / \xA712."
2448
- },
2449
- 501
2450
- );
2451
- };
2452
- }
2453
-
2454
2109
  // src/handlers/dispatcher.ts
2455
2110
  function buildRouteTable(h) {
2456
2111
  const table = /* @__PURE__ */ new Map();
@@ -2480,10 +2135,6 @@ function buildRouteTable(h) {
2480
2135
  table.set("preview/enter", { POST: async (req) => h.preview.enter(req), GET: async (req) => h.preview.enterWithToken(req) });
2481
2136
  table.set("preview/exit", { POST: async (req) => h.preview.exit(req) });
2482
2137
  table.set("preview/issue", { POST: h.preview.issueToken });
2483
- table.set("template/list", { GET: h.template.list });
2484
- table.set("forms/list", { GET: h.formsList });
2485
- table.set("forms/read", { GET: h.formsRead });
2486
- table.set("forms/delete", { POST: h.formsDelete });
2487
2138
  return table;
2488
2139
  }
2489
2140
  function createagntcmsRouteHandler(opts) {
@@ -2497,19 +2148,15 @@ function createagntcmsRouteHandler(opts) {
2497
2148
  // factory branches on `deps?.tokenStore` and `deps?.cookieName`).
2498
2149
  preview: createPreviewHandler(opts.preview),
2499
2150
  events: createEventsHandler(opts.events),
2500
- mcp: createMcpHandler(opts.mcp),
2501
- template: createTemplateHandler(opts.template),
2502
- formsList: createFormsListHandler(opts.formsList),
2503
- formsRead: createFormsReadHandler(opts.formsRead),
2504
- formsDelete: createFormsDeleteHandler()
2151
+ mcp: createMcpHandler(opts.mcp)
2505
2152
  };
2506
2153
  const table = buildRouteTable(handlers);
2507
2154
  const dispatch = async (method, req, ctx) => {
2508
- const { path: path6 } = await ctx.params;
2509
- if (!path6 || path6.length === 0) {
2155
+ const { path: path5 } = await ctx.params;
2156
+ if (!path5 || path5.length === 0) {
2510
2157
  return new Response(null, { status: 404 });
2511
2158
  }
2512
- const key = path6.join("/");
2159
+ const key = path5.join("/");
2513
2160
  const entry = table.get(key);
2514
2161
  if (!entry) {
2515
2162
  return new Response(null, { status: 404 });
@@ -2537,16 +2184,11 @@ export {
2537
2184
  createAssetsHandler,
2538
2185
  createDraftHandler,
2539
2186
  createEventsHandler,
2540
- createFormsDeleteHandler,
2541
- createFormsListHandler,
2542
- createFormsReadHandler,
2543
2187
  createGlobalHandler,
2544
2188
  createMcpHandler,
2545
2189
  createPageHandler,
2546
2190
  createPreviewHandler,
2547
2191
  createPreviewTokenStore,
2548
- createSubmitFormHandler,
2549
2192
  createTaskStore,
2550
- createTemplateHandler,
2551
2193
  createagntcmsRouteHandler
2552
2194
  };