@agntcms/next 0.3.2 → 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 +2 -123
- package/dist/config.d.cts +4 -59
- package/dist/config.d.ts +4 -59
- package/dist/config.mjs +2 -116
- 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
package/dist/server.cjs
CHANGED
|
@@ -32,13 +32,8 @@ var server_exports = {};
|
|
|
32
32
|
__export(server_exports, {
|
|
33
33
|
BooleanField: () => BooleanField,
|
|
34
34
|
ButtonField: () => ButtonField,
|
|
35
|
-
DuplicateFormNameError: () => DuplicateFormNameError,
|
|
36
|
-
FormOverridesField: () => FormOverridesField,
|
|
37
35
|
GlobalSlot: () => GlobalSlot,
|
|
38
|
-
HoneypotCollisionError: () => HoneypotCollisionError,
|
|
39
36
|
ImageField: () => ImageField,
|
|
40
|
-
InvalidFormFieldError: () => InvalidFormFieldError,
|
|
41
|
-
InvalidFormNameError: () => InvalidFormNameError,
|
|
42
37
|
LinkField: () => LinkField,
|
|
43
38
|
ListField: () => ListField,
|
|
44
39
|
NOT_FOUND_PAGE_SLUG: () => NOT_FOUND_PAGE_SLUG,
|
|
@@ -47,22 +42,14 @@ __export(server_exports, {
|
|
|
47
42
|
RichTextField: () => RichTextField,
|
|
48
43
|
SERVER_ERROR_PAGE_SLUG: () => SERVER_ERROR_PAGE_SLUG,
|
|
49
44
|
SelectField: () => SelectField,
|
|
50
|
-
SubmissionsNotReadableError: () => SubmissionsNotReadableError,
|
|
51
45
|
TextField: () => TextField,
|
|
52
46
|
VideoField: () => VideoField,
|
|
53
|
-
buildFormRegistry: () => buildFormRegistry,
|
|
54
47
|
createDefaultAssetAdapter: () => createDefaultAssetAdapter,
|
|
55
48
|
createDefaultContentAdapter: () => createDefaultContentAdapter,
|
|
56
|
-
createDefaultSubmissionAdapter: () => createDefaultSubmissionAdapter,
|
|
57
49
|
createFsAssetAdapter: () => createFsAssetAdapter,
|
|
58
50
|
createFsContentAdapter: () => createFsContentAdapter,
|
|
59
|
-
createFsSubmissionAdapter: () => createFsSubmissionAdapter,
|
|
60
51
|
createListPages: () => createListPages,
|
|
61
|
-
createRateLimit: () => createRateLimit,
|
|
62
52
|
createRuntime: () => createRuntime,
|
|
63
|
-
createSubmitForm: () => createSubmitForm,
|
|
64
|
-
createWebhookSubmissionAdapter: () => createWebhookSubmissionAdapter,
|
|
65
|
-
defineForm: () => defineForm,
|
|
66
53
|
defineSection: () => defineSection,
|
|
67
54
|
getReservedPageSlugViolation: () => getReservedPageSlugViolation,
|
|
68
55
|
hasUniqueSectionIds: () => hasUniqueSectionIds,
|
|
@@ -415,37 +402,6 @@ function normalizeLinkValue(raw) {
|
|
|
415
402
|
return { type: "internal", slug: "", label: "" };
|
|
416
403
|
}
|
|
417
404
|
|
|
418
|
-
// src/domain/form.ts
|
|
419
|
-
var FORM_FORBIDDEN_KINDS = /* @__PURE__ */ new Set([
|
|
420
|
-
"image",
|
|
421
|
-
"video",
|
|
422
|
-
"reference",
|
|
423
|
-
"list",
|
|
424
|
-
// `formOverrides` is a section-only descriptor (it overrides another
|
|
425
|
-
// form schema instance). Putting it inside a form would mean a form's
|
|
426
|
-
// payload could carry overrides for itself or another form — a
|
|
427
|
-
// recursive shape with no ergonomic editor UI. Section-only by design.
|
|
428
|
-
"formOverrides",
|
|
429
|
-
// `button` is a section-only descriptor: a styled CTA with an
|
|
430
|
-
// optional link. Public-form payloads collect user input — a button
|
|
431
|
-
// value is authored content, not a submitted answer. Section-only
|
|
432
|
-
// by design (mirrors `formOverrides`).
|
|
433
|
-
"button"
|
|
434
|
-
]);
|
|
435
|
-
var SubmissionsNotReadableError = class extends Error {
|
|
436
|
-
constructor(message = "submission adapter does not support reading") {
|
|
437
|
-
super(message);
|
|
438
|
-
this.name = "SubmissionsNotReadableError";
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
// src/domain/formOverrides.ts
|
|
443
|
-
var FormOverridesField = (formName, opts) => ({
|
|
444
|
-
kind: "formOverrides",
|
|
445
|
-
formName,
|
|
446
|
-
...opts?.default !== void 0 ? { default: opts.default } : {}
|
|
447
|
-
});
|
|
448
|
-
|
|
449
405
|
// src/storage/fs/content.ts
|
|
450
406
|
var SLUG_PATTERN2 = /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/;
|
|
451
407
|
var assertValidSlug = (slug) => {
|
|
@@ -506,7 +462,7 @@ var createFsContentAdapter = (options) => {
|
|
|
506
462
|
throw err;
|
|
507
463
|
}
|
|
508
464
|
};
|
|
509
|
-
const
|
|
465
|
+
const listJsonFiles = async (dir) => {
|
|
510
466
|
let entries;
|
|
511
467
|
try {
|
|
512
468
|
entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
@@ -520,7 +476,7 @@ var createFsContentAdapter = (options) => {
|
|
|
520
476
|
results.push(entry.name);
|
|
521
477
|
} else if (entry.isDirectory()) {
|
|
522
478
|
const subDir = path3.join(dir, entry.name);
|
|
523
|
-
const subFiles = await
|
|
479
|
+
const subFiles = await listJsonFiles(subDir);
|
|
524
480
|
for (const sub of subFiles) {
|
|
525
481
|
results.push(`${entry.name}/${sub}`);
|
|
526
482
|
}
|
|
@@ -559,7 +515,7 @@ var createFsContentAdapter = (options) => {
|
|
|
559
515
|
await writeAtomic(filePath, JSON.stringify(page, null, 2));
|
|
560
516
|
};
|
|
561
517
|
const listDrafts = async () => {
|
|
562
|
-
const files = await
|
|
518
|
+
const files = await listJsonFiles(draftsDir);
|
|
563
519
|
const results = [];
|
|
564
520
|
for (const relPath of files) {
|
|
565
521
|
const slug = relPath.slice(0, -".json".length);
|
|
@@ -569,7 +525,7 @@ var createFsContentAdapter = (options) => {
|
|
|
569
525
|
return results;
|
|
570
526
|
};
|
|
571
527
|
const listPages = async () => {
|
|
572
|
-
const files = await
|
|
528
|
+
const files = await listJsonFiles(pagesDir);
|
|
573
529
|
const results = [];
|
|
574
530
|
for (const relPath of files) {
|
|
575
531
|
const slug = relPath.slice(0, -".json".length);
|
|
@@ -579,7 +535,7 @@ var createFsContentAdapter = (options) => {
|
|
|
579
535
|
return results;
|
|
580
536
|
};
|
|
581
537
|
const listPageSummaries = async () => {
|
|
582
|
-
const files = await
|
|
538
|
+
const files = await listJsonFiles(pagesDir);
|
|
583
539
|
const results = [];
|
|
584
540
|
for (const relPath of files) {
|
|
585
541
|
const slug = relPath.slice(0, -".json".length);
|
|
@@ -877,151 +833,6 @@ var createFsContentAdapter = (options) => {
|
|
|
877
833
|
};
|
|
878
834
|
};
|
|
879
835
|
|
|
880
|
-
// src/storage/fs/submissions.ts
|
|
881
|
-
var import_node_crypto2 = require("crypto");
|
|
882
|
-
var fs4 = __toESM(require("fs/promises"), 1);
|
|
883
|
-
var path4 = __toESM(require("path"), 1);
|
|
884
|
-
var DEFAULT_MAX_LIST = 500;
|
|
885
|
-
var FORM_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
886
|
-
var parseSubmission = (raw) => {
|
|
887
|
-
let parsed;
|
|
888
|
-
try {
|
|
889
|
-
parsed = JSON.parse(raw);
|
|
890
|
-
} catch {
|
|
891
|
-
return null;
|
|
892
|
-
}
|
|
893
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
894
|
-
return null;
|
|
895
|
-
}
|
|
896
|
-
const obj = parsed;
|
|
897
|
-
if (typeof obj["formName"] !== "string") return null;
|
|
898
|
-
if (typeof obj["id"] !== "string") return null;
|
|
899
|
-
if (typeof obj["submittedAt"] !== "string") return null;
|
|
900
|
-
if (obj["payload"] === null || typeof obj["payload"] !== "object" || Array.isArray(obj["payload"])) {
|
|
901
|
-
return null;
|
|
902
|
-
}
|
|
903
|
-
return {
|
|
904
|
-
formName: obj["formName"],
|
|
905
|
-
id: obj["id"],
|
|
906
|
-
submittedAt: obj["submittedAt"],
|
|
907
|
-
payload: obj["payload"]
|
|
908
|
-
};
|
|
909
|
-
};
|
|
910
|
-
var assertValidFormName = (name) => {
|
|
911
|
-
if (typeof name !== "string" || !FORM_NAME_PATTERN.test(name)) {
|
|
912
|
-
throw new Error(`invalid form name: ${JSON.stringify(name)}`);
|
|
913
|
-
}
|
|
914
|
-
};
|
|
915
|
-
var submissionFilename = (submittedAt, id) => {
|
|
916
|
-
const ts = submittedAt.replace(/:/g, "-");
|
|
917
|
-
return `${ts}-${id}.json`;
|
|
918
|
-
};
|
|
919
|
-
var listJsonFiles = async (dir) => {
|
|
920
|
-
let entries;
|
|
921
|
-
try {
|
|
922
|
-
entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
923
|
-
} catch (err) {
|
|
924
|
-
if (isEnoent(err)) return [];
|
|
925
|
-
throw err;
|
|
926
|
-
}
|
|
927
|
-
const results = [];
|
|
928
|
-
for (const entry of entries) {
|
|
929
|
-
if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
930
|
-
results.push(entry.name);
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
return results;
|
|
934
|
-
};
|
|
935
|
-
var createFsSubmissionAdapter = (options) => {
|
|
936
|
-
const { submissionsRoot } = options;
|
|
937
|
-
if (!path4.isAbsolute(submissionsRoot)) {
|
|
938
|
-
throw new Error(
|
|
939
|
-
`submissionsRoot must be an absolute path, got: ${JSON.stringify(submissionsRoot)}`
|
|
940
|
-
);
|
|
941
|
-
}
|
|
942
|
-
const maxList = options.maxList ?? DEFAULT_MAX_LIST;
|
|
943
|
-
if (!Number.isFinite(maxList) || maxList <= 0 || !Number.isInteger(maxList)) {
|
|
944
|
-
throw new Error(
|
|
945
|
-
`maxList must be a positive integer, got: ${maxList}`
|
|
946
|
-
);
|
|
947
|
-
}
|
|
948
|
-
const rootResolved = path4.resolve(submissionsRoot);
|
|
949
|
-
const rootWithSep = rootResolved.endsWith(path4.sep) ? rootResolved : rootResolved + path4.sep;
|
|
950
|
-
const formDir = (formName) => {
|
|
951
|
-
assertValidFormName(formName);
|
|
952
|
-
const dir = path4.resolve(rootResolved, formName);
|
|
953
|
-
if (!dir.startsWith(rootWithSep)) {
|
|
954
|
-
throw new Error(`form name escapes submissions root: ${JSON.stringify(formName)}`);
|
|
955
|
-
}
|
|
956
|
-
return dir;
|
|
957
|
-
};
|
|
958
|
-
const cryptoSuffix = () => (0, import_node_crypto2.randomUUID)();
|
|
959
|
-
const store = async (submission) => {
|
|
960
|
-
const dir = formDir(submission.formName);
|
|
961
|
-
const filename = submissionFilename(submission.submittedAt, submission.id);
|
|
962
|
-
if (filename.includes("/") || filename.includes("\\")) {
|
|
963
|
-
throw new Error(`submission id contains path separator: ${JSON.stringify(submission.id)}`);
|
|
964
|
-
}
|
|
965
|
-
const target = path4.join(dir, filename);
|
|
966
|
-
await writeAtomic(target, JSON.stringify(submission, null, 2), cryptoSuffix);
|
|
967
|
-
};
|
|
968
|
-
const list = async (formName) => {
|
|
969
|
-
const dir = formDir(formName);
|
|
970
|
-
const files = await listJsonFiles(dir);
|
|
971
|
-
const summaries = [];
|
|
972
|
-
for (const filename of files) {
|
|
973
|
-
const stem = filename.slice(0, -".json".length);
|
|
974
|
-
const lastDash = stem.lastIndexOf("-");
|
|
975
|
-
if (lastDash < 0) continue;
|
|
976
|
-
const tsRaw = stem.slice(0, lastDash);
|
|
977
|
-
const id = stem.slice(lastDash + 1);
|
|
978
|
-
if (id === "") continue;
|
|
979
|
-
const tIndex = tsRaw.indexOf("T");
|
|
980
|
-
if (tIndex < 0) continue;
|
|
981
|
-
const datePart = tsRaw.slice(0, tIndex);
|
|
982
|
-
const timePart = tsRaw.slice(tIndex + 1).replace(/-/g, ":");
|
|
983
|
-
const submittedAt = `${datePart}T${timePart}`;
|
|
984
|
-
summaries.push({ id, submittedAt });
|
|
985
|
-
}
|
|
986
|
-
summaries.sort((a, b) => {
|
|
987
|
-
if (a.submittedAt !== b.submittedAt) {
|
|
988
|
-
return a.submittedAt < b.submittedAt ? 1 : -1;
|
|
989
|
-
}
|
|
990
|
-
if (a.id !== b.id) {
|
|
991
|
-
return a.id < b.id ? 1 : -1;
|
|
992
|
-
}
|
|
993
|
-
return 0;
|
|
994
|
-
});
|
|
995
|
-
return summaries.length > maxList ? summaries.slice(0, maxList) : summaries;
|
|
996
|
-
};
|
|
997
|
-
const read = async (formName, id) => {
|
|
998
|
-
if (id.includes("/") || id.includes("\\") || id.includes("..")) {
|
|
999
|
-
return null;
|
|
1000
|
-
}
|
|
1001
|
-
const dir = formDir(formName);
|
|
1002
|
-
let entries;
|
|
1003
|
-
try {
|
|
1004
|
-
entries = (await fs4.readdir(dir)).filter((n) => n.endsWith(".json"));
|
|
1005
|
-
} catch (err) {
|
|
1006
|
-
if (isEnoent(err)) return null;
|
|
1007
|
-
throw err;
|
|
1008
|
-
}
|
|
1009
|
-
const suffix = `-${id}.json`;
|
|
1010
|
-
const found = entries.find((n) => n.endsWith(suffix));
|
|
1011
|
-
if (!found) return null;
|
|
1012
|
-
const target = path4.join(dir, found);
|
|
1013
|
-
let raw;
|
|
1014
|
-
try {
|
|
1015
|
-
raw = await fs4.readFile(target, { encoding: "utf8" });
|
|
1016
|
-
} catch (err) {
|
|
1017
|
-
if (isEnoent(err)) return null;
|
|
1018
|
-
throw err;
|
|
1019
|
-
}
|
|
1020
|
-
return parseSubmission(raw);
|
|
1021
|
-
};
|
|
1022
|
-
return { info: { kind: "fs" }, store, list, read };
|
|
1023
|
-
};
|
|
1024
|
-
|
|
1025
836
|
// src/config/defaults-registry.ts
|
|
1026
837
|
var SLOT = /* @__PURE__ */ Symbol.for("@agntcms/next/default-adapter-factories");
|
|
1027
838
|
function holder() {
|
|
@@ -1032,43 +843,36 @@ function registerDefaultAdapterFactories(factories) {
|
|
|
1032
843
|
}
|
|
1033
844
|
|
|
1034
845
|
// src/config/defaults.ts
|
|
1035
|
-
var
|
|
846
|
+
var path4 = __toESM(require("path"), 1);
|
|
1036
847
|
function createDefaultContentAdapter(options) {
|
|
1037
848
|
const root = options?.projectRoot ?? process.cwd();
|
|
1038
849
|
return createFsContentAdapter({
|
|
1039
|
-
contentRoot:
|
|
850
|
+
contentRoot: path4.resolve(root, "content")
|
|
1040
851
|
});
|
|
1041
852
|
}
|
|
1042
853
|
function createDefaultAssetAdapter(options) {
|
|
1043
854
|
const root = options?.projectRoot ?? process.cwd();
|
|
1044
855
|
return createFsAssetAdapter({
|
|
1045
|
-
assetsRoot:
|
|
856
|
+
assetsRoot: path4.resolve(root, "public/assets"),
|
|
1046
857
|
publicUrlBase: "/assets"
|
|
1047
858
|
});
|
|
1048
859
|
}
|
|
1049
|
-
function createDefaultSubmissionAdapter(options) {
|
|
1050
|
-
const root = options?.projectRoot ?? process.cwd();
|
|
1051
|
-
return createFsSubmissionAdapter({
|
|
1052
|
-
submissionsRoot: path5.resolve(root, "content/submissions")
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
860
|
function installDefaultAdapterFactories() {
|
|
1056
861
|
const factories = {
|
|
1057
862
|
content: createDefaultContentAdapter,
|
|
1058
|
-
asset: createDefaultAssetAdapter
|
|
1059
|
-
submission: createDefaultSubmissionAdapter
|
|
863
|
+
asset: createDefaultAssetAdapter
|
|
1060
864
|
};
|
|
1061
865
|
registerDefaultAdapterFactories(factories);
|
|
1062
866
|
}
|
|
1063
867
|
|
|
1064
868
|
// src/runtime/getContent.ts
|
|
1065
|
-
var
|
|
869
|
+
var import_node_crypto3 = require("crypto");
|
|
1066
870
|
|
|
1067
871
|
// src/runtime/getGlobal.ts
|
|
1068
|
-
var
|
|
872
|
+
var import_node_crypto2 = require("crypto");
|
|
1069
873
|
var computeRevision = (global) => {
|
|
1070
874
|
const serialized = JSON.stringify(global);
|
|
1071
|
-
return (0,
|
|
875
|
+
return (0, import_node_crypto2.createHash)("sha256").update(serialized).digest("hex");
|
|
1072
876
|
};
|
|
1073
877
|
var wrapGlobalData = (global, revision) => {
|
|
1074
878
|
const data = global.data;
|
|
@@ -1165,160 +969,6 @@ var createListPages = ({
|
|
|
1165
969
|
};
|
|
1166
970
|
};
|
|
1167
971
|
|
|
1168
|
-
// src/runtime/submitForm.ts
|
|
1169
|
-
var import_node_crypto4 = require("crypto");
|
|
1170
|
-
var CROCKFORD32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
1171
|
-
var defaultGenerateId = () => {
|
|
1172
|
-
const bytes = (0, import_node_crypto4.randomBytes)(16);
|
|
1173
|
-
let out = "";
|
|
1174
|
-
for (let i = 0; i < 16; i++) {
|
|
1175
|
-
out += CROCKFORD32[bytes[i] & 31];
|
|
1176
|
-
}
|
|
1177
|
-
return out;
|
|
1178
|
-
};
|
|
1179
|
-
var validateNonEmptyString = (value) => {
|
|
1180
|
-
if (typeof value !== "string") return "must be a string";
|
|
1181
|
-
if (value.trim() === "") return "must not be empty";
|
|
1182
|
-
return null;
|
|
1183
|
-
};
|
|
1184
|
-
var validateNumber = (value, descriptor) => {
|
|
1185
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1186
|
-
return "must be a finite number";
|
|
1187
|
-
}
|
|
1188
|
-
if (descriptor.min !== void 0 && value < descriptor.min) {
|
|
1189
|
-
return `must be >= ${descriptor.min}`;
|
|
1190
|
-
}
|
|
1191
|
-
if (descriptor.max !== void 0 && value > descriptor.max) {
|
|
1192
|
-
return `must be <= ${descriptor.max}`;
|
|
1193
|
-
}
|
|
1194
|
-
return null;
|
|
1195
|
-
};
|
|
1196
|
-
var validateBoolean = (value) => {
|
|
1197
|
-
if (typeof value !== "boolean") return "must be true or false";
|
|
1198
|
-
return null;
|
|
1199
|
-
};
|
|
1200
|
-
var validateSelect = (value, descriptor) => {
|
|
1201
|
-
if (typeof value !== "string") return "must be a string";
|
|
1202
|
-
if (!descriptor.options.some((opt) => opt.value === value)) {
|
|
1203
|
-
return "must be one of the declared options";
|
|
1204
|
-
}
|
|
1205
|
-
return null;
|
|
1206
|
-
};
|
|
1207
|
-
var validateLinkPayload = (value) => {
|
|
1208
|
-
if (value === null || typeof value !== "object") return "must be a link object";
|
|
1209
|
-
const obj = value;
|
|
1210
|
-
if (typeof obj["label"] !== "string") return "label must be a string";
|
|
1211
|
-
if (obj["type"] === "internal") {
|
|
1212
|
-
const slug = obj["slug"];
|
|
1213
|
-
if (typeof slug !== "string") return "slug must be a string";
|
|
1214
|
-
if (slug.trim() === "") return "slug must be a non-empty string";
|
|
1215
|
-
return validateInternalSlug(slug);
|
|
1216
|
-
}
|
|
1217
|
-
if (obj["type"] === "external") {
|
|
1218
|
-
const url = obj["url"];
|
|
1219
|
-
if (typeof url !== "string") return "url must be a string";
|
|
1220
|
-
if (url.trim() === "") return "url must be a non-empty string";
|
|
1221
|
-
return validateExternalUrl(url);
|
|
1222
|
-
}
|
|
1223
|
-
if (obj["type"] === "email") {
|
|
1224
|
-
const email = obj["email"];
|
|
1225
|
-
if (typeof email !== "string") return "email must be a string";
|
|
1226
|
-
if (email.trim() === "") return "email must be a non-empty string";
|
|
1227
|
-
return validateEmail(email);
|
|
1228
|
-
}
|
|
1229
|
-
if (obj["type"] === "phone") {
|
|
1230
|
-
const phone = obj["phone"];
|
|
1231
|
-
if (typeof phone !== "string") return "phone must be a string";
|
|
1232
|
-
if (phone.trim() === "") return "phone must be a non-empty string";
|
|
1233
|
-
return validatePhone(phone);
|
|
1234
|
-
}
|
|
1235
|
-
return 'type must be "internal", "external", "email", or "phone"';
|
|
1236
|
-
};
|
|
1237
|
-
var validateAndNormalisePayload = (schema, payload) => {
|
|
1238
|
-
const errors = {};
|
|
1239
|
-
const normalised = {};
|
|
1240
|
-
for (const [fieldName, descriptor] of Object.entries(schema)) {
|
|
1241
|
-
if (!Object.prototype.hasOwnProperty.call(payload, fieldName)) {
|
|
1242
|
-
errors[fieldName] = "is required";
|
|
1243
|
-
continue;
|
|
1244
|
-
}
|
|
1245
|
-
const value = payload[fieldName];
|
|
1246
|
-
let err = null;
|
|
1247
|
-
switch (descriptor.kind) {
|
|
1248
|
-
case "text":
|
|
1249
|
-
case "richText": {
|
|
1250
|
-
err = validateNonEmptyString(value);
|
|
1251
|
-
if (!err) {
|
|
1252
|
-
normalised[fieldName] = value.trim();
|
|
1253
|
-
}
|
|
1254
|
-
break;
|
|
1255
|
-
}
|
|
1256
|
-
case "number": {
|
|
1257
|
-
err = validateNumber(value, descriptor);
|
|
1258
|
-
if (!err) normalised[fieldName] = value;
|
|
1259
|
-
break;
|
|
1260
|
-
}
|
|
1261
|
-
case "boolean": {
|
|
1262
|
-
err = validateBoolean(value);
|
|
1263
|
-
if (!err) normalised[fieldName] = value;
|
|
1264
|
-
break;
|
|
1265
|
-
}
|
|
1266
|
-
case "select": {
|
|
1267
|
-
err = validateSelect(value, descriptor);
|
|
1268
|
-
if (!err) normalised[fieldName] = value;
|
|
1269
|
-
break;
|
|
1270
|
-
}
|
|
1271
|
-
case "link": {
|
|
1272
|
-
err = validateLinkPayload(value);
|
|
1273
|
-
if (!err) {
|
|
1274
|
-
const linkObj = value;
|
|
1275
|
-
const label = typeof linkObj["label"] === "string" ? linkObj["label"] : "";
|
|
1276
|
-
const normalisedLink = linkObj["type"] === "external" ? { type: "external", url: linkObj["url"], label } : linkObj["type"] === "email" ? { type: "email", email: linkObj["email"], label } : linkObj["type"] === "phone" ? { type: "phone", phone: linkObj["phone"], label } : { type: "internal", slug: linkObj["slug"], label };
|
|
1277
|
-
normalised[fieldName] = normalisedLink;
|
|
1278
|
-
}
|
|
1279
|
-
break;
|
|
1280
|
-
}
|
|
1281
|
-
default: {
|
|
1282
|
-
const _exhaustive = descriptor;
|
|
1283
|
-
void _exhaustive;
|
|
1284
|
-
err = "unsupported field type";
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
if (err) errors[fieldName] = err;
|
|
1288
|
-
}
|
|
1289
|
-
if (Object.keys(errors).length > 0) return { ok: false, errors };
|
|
1290
|
-
return { ok: true, payload: normalised };
|
|
1291
|
-
};
|
|
1292
|
-
function createSubmitForm(deps) {
|
|
1293
|
-
const { forms, submissionAdapter } = deps;
|
|
1294
|
-
const generateId = deps.generateId ?? defaultGenerateId;
|
|
1295
|
-
const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
1296
|
-
return async function submitForm(input) {
|
|
1297
|
-
const def = forms.get(input.formName);
|
|
1298
|
-
if (!def) {
|
|
1299
|
-
return { ok: false, error: "unknown_form" };
|
|
1300
|
-
}
|
|
1301
|
-
if (def.honeypot !== void 0) {
|
|
1302
|
-
const trapValue = input.payload[def.honeypot];
|
|
1303
|
-
if (typeof trapValue === "string" && trapValue.length > 0) {
|
|
1304
|
-
return { ok: true, stored: false, suppressed: "honeypot" };
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
const validated = validateAndNormalisePayload(def.schema, input.payload);
|
|
1308
|
-
if (!validated.ok) {
|
|
1309
|
-
return { ok: false, error: "validation_failed", errors: validated.errors };
|
|
1310
|
-
}
|
|
1311
|
-
const submission = {
|
|
1312
|
-
formName: def.name,
|
|
1313
|
-
payload: validated.payload,
|
|
1314
|
-
submittedAt: now(),
|
|
1315
|
-
id: generateId()
|
|
1316
|
-
};
|
|
1317
|
-
await submissionAdapter.store(submission);
|
|
1318
|
-
return { ok: true, stored: true, id: submission.id };
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
972
|
// src/runtime/getContent.ts
|
|
1323
973
|
var isPlainObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
1324
974
|
var looksLikeLink = (obj) => {
|
|
@@ -1367,7 +1017,7 @@ var normalizeLinksInSections = (sections) => {
|
|
|
1367
1017
|
};
|
|
1368
1018
|
var computeRevision2 = (page) => {
|
|
1369
1019
|
const serialized = JSON.stringify(page);
|
|
1370
|
-
return (0,
|
|
1020
|
+
return (0, import_node_crypto3.createHash)("sha256").update(serialized).digest("hex");
|
|
1371
1021
|
};
|
|
1372
1022
|
var withSections = (page, sections) => ({
|
|
1373
1023
|
...page,
|
|
@@ -1478,83 +1128,7 @@ function createRuntime(options) {
|
|
|
1478
1128
|
};
|
|
1479
1129
|
const getGlobal = createGetGlobal(contentAdapter);
|
|
1480
1130
|
const listPages = createListPages({ contentAdapter });
|
|
1481
|
-
|
|
1482
|
-
info: { kind: "fs" },
|
|
1483
|
-
store: async () => {
|
|
1484
|
-
throw new Error("submissionAdapter not configured; pass one to createRuntime");
|
|
1485
|
-
},
|
|
1486
|
-
list: async () => [],
|
|
1487
|
-
read: async () => null
|
|
1488
|
-
};
|
|
1489
|
-
const submitForm = createSubmitForm({
|
|
1490
|
-
forms: options.forms ?? emptyFormRegistry,
|
|
1491
|
-
submissionAdapter: options.submissionAdapter ?? noopAdapter
|
|
1492
|
-
});
|
|
1493
|
-
return { getContent, publishDraft, getGlobal, submitForm, listPages };
|
|
1494
|
-
}
|
|
1495
|
-
var emptyFormRegistry = Object.freeze({
|
|
1496
|
-
definitions: [],
|
|
1497
|
-
get: () => void 0,
|
|
1498
|
-
has: () => false
|
|
1499
|
-
});
|
|
1500
|
-
|
|
1501
|
-
// src/runtime/rateLimit.ts
|
|
1502
|
-
var DEFAULT_MAX_BUCKETS = 1e4;
|
|
1503
|
-
function createRateLimit(options) {
|
|
1504
|
-
const { perWindow, windowMs } = options;
|
|
1505
|
-
if (!Number.isFinite(perWindow) || perWindow <= 0) {
|
|
1506
|
-
throw new Error(`perWindow must be a positive number, got: ${perWindow}`);
|
|
1507
|
-
}
|
|
1508
|
-
if (!Number.isFinite(windowMs) || windowMs <= 0) {
|
|
1509
|
-
throw new Error(`windowMs must be a positive number, got: ${windowMs}`);
|
|
1510
|
-
}
|
|
1511
|
-
const maxBuckets = options.maxBuckets ?? DEFAULT_MAX_BUCKETS;
|
|
1512
|
-
if (!Number.isFinite(maxBuckets) || maxBuckets <= 0 || !Number.isInteger(maxBuckets)) {
|
|
1513
|
-
throw new Error(`maxBuckets must be a positive integer, got: ${maxBuckets}`);
|
|
1514
|
-
}
|
|
1515
|
-
const now = options.now ?? Date.now;
|
|
1516
|
-
const buckets = /* @__PURE__ */ new Map();
|
|
1517
|
-
const keyOf = (ip, formName) => `${ip}:${formName}`;
|
|
1518
|
-
const sweepExpired = (t) => {
|
|
1519
|
-
for (const [k, b] of buckets) {
|
|
1520
|
-
if (t >= b.resetAt) buckets.delete(k);
|
|
1521
|
-
}
|
|
1522
|
-
};
|
|
1523
|
-
const evictOldest = () => {
|
|
1524
|
-
let oldestKey = null;
|
|
1525
|
-
let oldestResetAt = Number.POSITIVE_INFINITY;
|
|
1526
|
-
for (const [k, b] of buckets) {
|
|
1527
|
-
if (b.resetAt < oldestResetAt) {
|
|
1528
|
-
oldestResetAt = b.resetAt;
|
|
1529
|
-
oldestKey = k;
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
if (oldestKey !== null) buckets.delete(oldestKey);
|
|
1533
|
-
};
|
|
1534
|
-
return {
|
|
1535
|
-
check: (ip, formName) => {
|
|
1536
|
-
const key = keyOf(ip, formName);
|
|
1537
|
-
const t = now();
|
|
1538
|
-
const existing = buckets.get(key);
|
|
1539
|
-
if (!existing || t >= existing.resetAt) {
|
|
1540
|
-
if (!existing && buckets.size >= maxBuckets) {
|
|
1541
|
-
sweepExpired(t);
|
|
1542
|
-
while (buckets.size >= maxBuckets) {
|
|
1543
|
-
evictOldest();
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
const bucket = { count: 1, resetAt: t + windowMs };
|
|
1547
|
-
buckets.set(key, bucket);
|
|
1548
|
-
return { allowed: true, count: 1, resetAt: bucket.resetAt };
|
|
1549
|
-
}
|
|
1550
|
-
existing.count += 1;
|
|
1551
|
-
const allowed = existing.count <= perWindow;
|
|
1552
|
-
return { allowed, count: existing.count, resetAt: existing.resetAt };
|
|
1553
|
-
},
|
|
1554
|
-
reset: () => {
|
|
1555
|
-
buckets.clear();
|
|
1556
|
-
}
|
|
1557
|
-
};
|
|
1131
|
+
return { getContent, publishDraft, getGlobal, listPages };
|
|
1558
1132
|
}
|
|
1559
1133
|
|
|
1560
1134
|
// src/runtime/systemPages.ts
|
|
@@ -1592,95 +1166,6 @@ var isSitemapEligibleSlug = (slug) => {
|
|
|
1592
1166
|
return !SITEMAP_EXCLUDED_TERMINAL_SLUGS.has(terminal);
|
|
1593
1167
|
};
|
|
1594
1168
|
|
|
1595
|
-
// src/storage/webhook/submissions.ts
|
|
1596
|
-
var URL_PATTERN = /^https?:\/\//;
|
|
1597
|
-
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
1598
|
-
var createWebhookSubmissionAdapter = (options) => {
|
|
1599
|
-
if (typeof options.url !== "string" || !URL_PATTERN.test(options.url)) {
|
|
1600
|
-
throw new Error(
|
|
1601
|
-
`webhook url must start with http:// or https://, got: ${JSON.stringify(options.url)}`
|
|
1602
|
-
);
|
|
1603
|
-
}
|
|
1604
|
-
let parsedHost;
|
|
1605
|
-
try {
|
|
1606
|
-
parsedHost = new URL(options.url).host;
|
|
1607
|
-
} catch {
|
|
1608
|
-
throw new Error(
|
|
1609
|
-
`webhook url is not a valid URL: ${JSON.stringify(options.url)}`
|
|
1610
|
-
);
|
|
1611
|
-
}
|
|
1612
|
-
if (options.url.startsWith("http://") && options.headers !== void 0 && Object.keys(options.headers).length > 0) {
|
|
1613
|
-
console.warn(
|
|
1614
|
-
"[agntcms] webhook url uses http:// with custom headers \u2014 secrets will be transmitted in plaintext"
|
|
1615
|
-
);
|
|
1616
|
-
}
|
|
1617
|
-
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1618
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || !Number.isInteger(timeoutMs)) {
|
|
1619
|
-
throw new Error(
|
|
1620
|
-
`webhook timeoutMs must be a positive integer (ms), got: ${timeoutMs}`
|
|
1621
|
-
);
|
|
1622
|
-
}
|
|
1623
|
-
const doFetch = options.fetch ?? ((url, init) => (
|
|
1624
|
-
// The DOM/Node fetch types differ; cast to the minimal shape we declared.
|
|
1625
|
-
// Using `globalThis.fetch` keeps this neutral across Node, Edge, and
|
|
1626
|
-
// jsdom test environments.
|
|
1627
|
-
globalThis.fetch(url, init)
|
|
1628
|
-
));
|
|
1629
|
-
const baseHeaders = {
|
|
1630
|
-
"Content-Type": "application/json",
|
|
1631
|
-
...options.headers
|
|
1632
|
-
};
|
|
1633
|
-
const store = async (submission) => {
|
|
1634
|
-
const controller = new AbortController();
|
|
1635
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1636
|
-
let res;
|
|
1637
|
-
try {
|
|
1638
|
-
res = await doFetch(options.url, {
|
|
1639
|
-
method: "POST",
|
|
1640
|
-
headers: baseHeaders,
|
|
1641
|
-
body: JSON.stringify(submission),
|
|
1642
|
-
signal: controller.signal
|
|
1643
|
-
});
|
|
1644
|
-
} catch (err) {
|
|
1645
|
-
const isAbort = controller.signal.aborted || err instanceof Error && err.name === "AbortError";
|
|
1646
|
-
if (isAbort) {
|
|
1647
|
-
console.error(
|
|
1648
|
-
`[agntcms] webhook submission timed out after ${timeoutMs}ms`
|
|
1649
|
-
);
|
|
1650
|
-
throw new Error(`webhook request timed out after ${timeoutMs}ms`);
|
|
1651
|
-
}
|
|
1652
|
-
console.error(
|
|
1653
|
-
`[agntcms] webhook submission failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1654
|
-
);
|
|
1655
|
-
throw err;
|
|
1656
|
-
} finally {
|
|
1657
|
-
clearTimeout(timer);
|
|
1658
|
-
}
|
|
1659
|
-
if (!res.ok) {
|
|
1660
|
-
let detail = "";
|
|
1661
|
-
try {
|
|
1662
|
-
detail = await res.text();
|
|
1663
|
-
} catch {
|
|
1664
|
-
}
|
|
1665
|
-
console.error(
|
|
1666
|
-
`[agntcms] webhook returned ${res.status}${detail ? `: ${detail.slice(0, 200)}` : ""}`
|
|
1667
|
-
);
|
|
1668
|
-
throw new Error(`webhook responded with status ${res.status}`);
|
|
1669
|
-
}
|
|
1670
|
-
};
|
|
1671
|
-
const list = async (_formName) => {
|
|
1672
|
-
throw new SubmissionsNotReadableError(
|
|
1673
|
-
"webhook submission adapter has no local copy; configure an FS adapter to enable listing"
|
|
1674
|
-
);
|
|
1675
|
-
};
|
|
1676
|
-
const read = async (_formName, _id) => {
|
|
1677
|
-
throw new SubmissionsNotReadableError(
|
|
1678
|
-
"webhook submission adapter has no local copy; configure an FS adapter to enable reading"
|
|
1679
|
-
);
|
|
1680
|
-
};
|
|
1681
|
-
return { info: { kind: "webhook", host: parsedHost }, store, list, read };
|
|
1682
|
-
};
|
|
1683
|
-
|
|
1684
1169
|
// src/sections/defineSection.ts
|
|
1685
1170
|
function builtInDefault(fieldName, descriptor) {
|
|
1686
1171
|
switch (descriptor.kind) {
|
|
@@ -1708,8 +1193,6 @@ function builtInDefault(fieldName, descriptor) {
|
|
|
1708
1193
|
return descriptor.options[0]?.value ?? "";
|
|
1709
1194
|
case "list":
|
|
1710
1195
|
return [];
|
|
1711
|
-
case "formOverrides":
|
|
1712
|
-
return {};
|
|
1713
1196
|
default: {
|
|
1714
1197
|
const _exhaustive = descriptor;
|
|
1715
1198
|
void _exhaustive;
|
|
@@ -1727,11 +1210,7 @@ function defineSection(input) {
|
|
|
1727
1210
|
...input.category !== void 0 ? { category: input.category } : {},
|
|
1728
1211
|
schema: input.schema,
|
|
1729
1212
|
component: input.component,
|
|
1730
|
-
defaults
|
|
1731
|
-
// Conditional spread mirrors the `category` pattern — required so
|
|
1732
|
-
// `exactOptionalPropertyTypes` does not see `layouts: undefined` being
|
|
1733
|
-
// assigned to an optional-only property.
|
|
1734
|
-
...input.layouts !== void 0 ? { layouts: input.layouts } : {}
|
|
1213
|
+
defaults
|
|
1735
1214
|
};
|
|
1736
1215
|
}
|
|
1737
1216
|
|
|
@@ -1832,105 +1311,14 @@ function renderFallback(fallback) {
|
|
|
1832
1311
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: fallback });
|
|
1833
1312
|
}
|
|
1834
1313
|
|
|
1835
|
-
// src/forms/defineForm.ts
|
|
1836
|
-
var InvalidFormFieldError = class extends Error {
|
|
1837
|
-
formName;
|
|
1838
|
-
fieldName;
|
|
1839
|
-
fieldKind;
|
|
1840
|
-
constructor(formName, fieldName, fieldKind) {
|
|
1841
|
-
super(
|
|
1842
|
-
`Form "${formName}": field "${fieldName}" uses kind "${fieldKind}", which is not allowed in a form schema in v1. Allowed kinds: text, richText, number, boolean, select, link. Forbidden kinds: image, reference, list, formOverrides. See ARCHITECTURE.md \xA76.5.`
|
|
1843
|
-
);
|
|
1844
|
-
this.name = "InvalidFormFieldError";
|
|
1845
|
-
this.formName = formName;
|
|
1846
|
-
this.fieldName = fieldName;
|
|
1847
|
-
this.fieldKind = fieldKind;
|
|
1848
|
-
}
|
|
1849
|
-
};
|
|
1850
|
-
var HoneypotCollisionError = class extends Error {
|
|
1851
|
-
formName;
|
|
1852
|
-
fieldName;
|
|
1853
|
-
reason;
|
|
1854
|
-
constructor(formName, fieldName, reason = "collision") {
|
|
1855
|
-
super(
|
|
1856
|
-
reason === "empty" ? `Form "${formName}": honeypot name must be a non-empty string.` : `Form "${formName}": honeypot name "${fieldName}" collides with a real field. Choose a honeypot name that does not appear in the schema.`
|
|
1857
|
-
);
|
|
1858
|
-
this.name = "HoneypotCollisionError";
|
|
1859
|
-
this.formName = formName;
|
|
1860
|
-
this.fieldName = fieldName;
|
|
1861
|
-
this.reason = reason;
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
|
-
var InvalidFormNameError = class extends Error {
|
|
1865
|
-
constructor(name) {
|
|
1866
|
-
super(
|
|
1867
|
-
`Invalid form name ${JSON.stringify(name)}. Use letters, digits, hyphen, and underscore only (no path separators).`
|
|
1868
|
-
);
|
|
1869
|
-
this.name = "InvalidFormNameError";
|
|
1870
|
-
}
|
|
1871
|
-
};
|
|
1872
|
-
var FORM_NAME_PATTERN2 = /^[a-zA-Z0-9_-]+$/;
|
|
1873
|
-
function defineForm(input) {
|
|
1874
|
-
if (typeof input.name !== "string" || !FORM_NAME_PATTERN2.test(input.name)) {
|
|
1875
|
-
throw new InvalidFormNameError(input.name);
|
|
1876
|
-
}
|
|
1877
|
-
for (const [fieldName, descriptor] of Object.entries(input.schema)) {
|
|
1878
|
-
const kind = descriptor.kind;
|
|
1879
|
-
if (FORM_FORBIDDEN_KINDS.has(kind)) {
|
|
1880
|
-
throw new InvalidFormFieldError(input.name, fieldName, kind);
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
if (input.honeypot !== void 0) {
|
|
1884
|
-
if (typeof input.honeypot !== "string" || input.honeypot === "") {
|
|
1885
|
-
throw new HoneypotCollisionError(input.name, input.honeypot, "empty");
|
|
1886
|
-
}
|
|
1887
|
-
if (Object.prototype.hasOwnProperty.call(input.schema, input.honeypot)) {
|
|
1888
|
-
throw new HoneypotCollisionError(input.name, input.honeypot, "collision");
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
return input.honeypot !== void 0 ? { name: input.name, schema: input.schema, honeypot: input.honeypot } : { name: input.name, schema: input.schema };
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
|
-
// src/forms/registry.ts
|
|
1895
|
-
var DuplicateFormNameError = class extends Error {
|
|
1896
|
-
formName;
|
|
1897
|
-
constructor(name) {
|
|
1898
|
-
super(
|
|
1899
|
-
`Form name "${name}" is registered more than once. Form names must be unique within a config.`
|
|
1900
|
-
);
|
|
1901
|
-
this.name = "DuplicateFormNameError";
|
|
1902
|
-
this.formName = name;
|
|
1903
|
-
}
|
|
1904
|
-
};
|
|
1905
|
-
function buildFormRegistry(definitions) {
|
|
1906
|
-
const byName = /* @__PURE__ */ new Map();
|
|
1907
|
-
for (const def of definitions) {
|
|
1908
|
-
if (byName.has(def.name)) {
|
|
1909
|
-
throw new DuplicateFormNameError(def.name);
|
|
1910
|
-
}
|
|
1911
|
-
byName.set(def.name, def);
|
|
1912
|
-
}
|
|
1913
|
-
const registry = {
|
|
1914
|
-
definitions,
|
|
1915
|
-
get: (name) => byName.get(name),
|
|
1916
|
-
has: (name) => byName.has(name)
|
|
1917
|
-
};
|
|
1918
|
-
return Object.freeze(registry);
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
1314
|
// src/server.ts
|
|
1922
1315
|
installDefaultAdapterFactories();
|
|
1923
1316
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1924
1317
|
0 && (module.exports = {
|
|
1925
1318
|
BooleanField,
|
|
1926
1319
|
ButtonField,
|
|
1927
|
-
DuplicateFormNameError,
|
|
1928
|
-
FormOverridesField,
|
|
1929
1320
|
GlobalSlot,
|
|
1930
|
-
HoneypotCollisionError,
|
|
1931
1321
|
ImageField,
|
|
1932
|
-
InvalidFormFieldError,
|
|
1933
|
-
InvalidFormNameError,
|
|
1934
1322
|
LinkField,
|
|
1935
1323
|
ListField,
|
|
1936
1324
|
NOT_FOUND_PAGE_SLUG,
|
|
@@ -1939,22 +1327,14 @@ installDefaultAdapterFactories();
|
|
|
1939
1327
|
RichTextField,
|
|
1940
1328
|
SERVER_ERROR_PAGE_SLUG,
|
|
1941
1329
|
SelectField,
|
|
1942
|
-
SubmissionsNotReadableError,
|
|
1943
1330
|
TextField,
|
|
1944
1331
|
VideoField,
|
|
1945
|
-
buildFormRegistry,
|
|
1946
1332
|
createDefaultAssetAdapter,
|
|
1947
1333
|
createDefaultContentAdapter,
|
|
1948
|
-
createDefaultSubmissionAdapter,
|
|
1949
1334
|
createFsAssetAdapter,
|
|
1950
1335
|
createFsContentAdapter,
|
|
1951
|
-
createFsSubmissionAdapter,
|
|
1952
1336
|
createListPages,
|
|
1953
|
-
createRateLimit,
|
|
1954
1337
|
createRuntime,
|
|
1955
|
-
createSubmitForm,
|
|
1956
|
-
createWebhookSubmissionAdapter,
|
|
1957
|
-
defineForm,
|
|
1958
1338
|
defineSection,
|
|
1959
1339
|
getReservedPageSlugViolation,
|
|
1960
1340
|
hasUniqueSectionIds,
|