@phtngyn/cms 0.2.0-beta.3 → 0.2.0-beta.5
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/README.md +31 -13
- package/package.json +7 -7
- package/src/ApplicationTypes.d.ts +3 -3
- package/src/Authoring.d.ts +11 -3
- package/src/{Configuration-BU-UyGoH.js → Configuration-JQ1qyaU0.js} +347 -189
- package/src/Configuration-JQ1qyaU0.js.map +1 -0
- package/src/Configuration.d.ts +1 -1
- package/src/Content.d.ts +7 -6
- package/src/Content.js +106 -47
- package/src/Content.js.map +1 -1
- package/src/ContentTransfer-BxwswWn3.js +86 -0
- package/src/ContentTransfer-BxwswWn3.js.map +1 -0
- package/src/{ContentTransfer-CRQet3QJ.d.ts → ContentTransfer-Z9FHyLez.d.ts} +33 -9
- package/src/{DocumentEngine-ClhFXW9M.js → DocumentEngine-j6Vi7nQo.js} +279 -178
- package/src/DocumentEngine-j6Vi7nQo.js.map +1 -0
- package/src/DocumentModel.d.ts +9 -2
- package/src/DocumentModel.js +17 -4
- package/src/DocumentModel.js.map +1 -1
- package/src/{Forms-DoB56hfe.js → Forms-CX-hwmJF.js} +18 -11
- package/src/Forms-CX-hwmJF.js.map +1 -0
- package/src/{Forms-BbkE7QfC.js → Forms-CfNPTiCr.js} +2 -2
- package/src/{Forms-BbkE7QfC.js.map → Forms-CfNPTiCr.js.map} +1 -1
- package/src/Media-j1bTritO.js +112 -0
- package/src/Media-j1bTritO.js.map +1 -0
- package/src/Module.js +0 -4
- package/src/Module.js.map +1 -1
- package/src/References-CCPDAPve.js +45 -0
- package/src/References-CCPDAPve.js.map +1 -0
- package/src/{S3MediaObjects-CR3p1WTg.js → S3MediaObjects-BRuPQbxl.js} +454 -516
- package/src/S3MediaObjects-BRuPQbxl.js.map +1 -0
- package/src/cli/content.js +6 -5
- package/src/cli/content.js.map +1 -1
- package/src/cli.js +16 -3
- package/src/cli.js.map +1 -1
- package/src/{connection-D5S9Iph-.js → connection-BP80q4d-.js} +2 -2
- package/src/{connection-D5S9Iph-.js.map → connection-BP80q4d-.js.map} +1 -1
- package/src/{dev-lifecycle-D3f9-upa.js → dev-lifecycle-DdBluSiR.js} +26 -6
- package/src/dev-lifecycle-DdBluSiR.js.map +1 -0
- package/src/{installation-fZtNxtoW.js → installation-BoG8E3nJ.js} +7982 -7155
- package/src/installation-BoG8E3nJ.js.map +1 -0
- package/src/internal/authoring-catalog.js +2 -2
- package/src/internal/authoring-compiler.js +35 -9
- package/src/internal/authoring-compiler.js.map +1 -1
- package/src/internal/authoring-metadata.js +14 -5
- package/src/internal/authoring-metadata.js.map +1 -1
- package/src/internal/configuration.js +27 -3
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/dev-lifecycle.js +2 -2
- package/src/internal/document-model.js +134 -43
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/field-metadata.js +2 -1
- package/src/internal/field-metadata.js.map +1 -1
- package/src/internal/form-capabilities.js +1 -1
- package/src/{location-CPX7oj0o.js → location-CMNGO3lU.js} +2 -2
- package/src/{location-CPX7oj0o.js.map → location-CMNGO3lU.js.map} +1 -1
- package/src/{metadata-BEZPWh-3.js → metadata-UzZmjwxM.js} +2 -2
- package/src/{metadata-BEZPWh-3.js.map → metadata-UzZmjwxM.js.map} +1 -1
- package/src/{models-C9kF9JlQ.js → models-5j67LMqW.js} +4 -4
- package/src/{models-C9kF9JlQ.js.map → models-5j67LMqW.js.map} +1 -1
- package/src/{models-ChRxBChy.js → models-VmGmG19-.js} +42 -130
- package/src/models-VmGmG19-.js.map +1 -0
- package/src/runtime/delivery/DocumentRenderer.js +5 -1
- package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
- package/src/runtime/delivery/context.js +1 -1
- package/src/runtime/delivery/document-page.js +1 -5
- package/src/runtime/delivery/document-page.js.map +1 -1
- package/src/runtime/delivery/plugin.js +34 -5
- package/src/runtime/delivery/plugin.js.map +1 -1
- package/src/runtime/delivery/preview.d.ts +1 -1
- package/src/runtime/delivery/types.d.ts +1 -1
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +2 -1
- package/src/runtime/delivery/useCmsDocumentSeo.js +5 -4
- package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
- package/src/runtime/forms/document.js +2 -2
- package/src/runtime/forms/useCmsForm.js +2 -2
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +1 -1
- package/src/runtime/preview/CmsStudioPreviewMarker.js +18 -4
- package/src/runtime/preview/CmsStudioPreviewMarker.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +65 -74
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/overlay.js +85 -28
- package/src/runtime/preview/overlay.js.map +1 -1
- package/src/runtime/preview/plugin.client.js +4 -4
- package/src/runtime/preview/preview.css +50 -36
- package/src/runtime/preview/protocol.d.ts +11 -5
- package/src/runtime/preview/protocol.js +17 -5
- package/src/runtime/preview/protocol.js.map +1 -1
- package/src/runtime/preview/regions.js +142 -0
- package/src/runtime/preview/regions.js.map +1 -0
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +9 -10
- package/src/runtime/sitemap.js.map +1 -1
- package/src/{scalars-B2lgGUnj.js → scalars-CVZqT3L0.js} +2 -6
- package/src/scalars-CVZqT3L0.js.map +1 -0
- package/src/{store-CCsjHaZm.js → store-PKKB8xa2.js} +49 -66
- package/src/store-PKKB8xa2.js.map +1 -0
- package/src/{types-DutFRtaG.d.ts → types-DZ0IV-Ow.d.ts} +14 -3
- package/studio/CreateDocumentDialog-vQ8hDs2C.js +253 -0
- package/studio/{documentPlanning-CDb31mnl.js → documentPlanning-Bx3W9KkD.js} +12054 -12085
- package/studio/{editor-Bzlh3zXt.js → editor-P2rB7Csp.js} +11228 -11927
- package/studio/host.css +1 -1
- package/studio/host.js +23595 -24903
- package/studio/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/src/Configuration-BU-UyGoH.js.map +0 -1
- package/src/ContentTransfer-BhF9G56s.js +0 -57
- package/src/ContentTransfer-BhF9G56s.js.map +0 -1
- package/src/DocumentEngine-ClhFXW9M.js.map +0 -1
- package/src/Forms-DoB56hfe.js.map +0 -1
- package/src/S3MediaObjects-CR3p1WTg.js.map +0 -1
- package/src/dev-lifecycle-D3f9-upa.js.map +0 -1
- package/src/installation-fZtNxtoW.js.map +0 -1
- package/src/models-ChRxBChy.js.map +0 -1
- package/src/runtime/preview/targets.js +0 -101
- package/src/runtime/preview/targets.js.map +0 -1
- package/src/scalars-B2lgGUnj.js.map +0 -1
- package/src/store-CCsjHaZm.js.map +0 -1
- package/studio/CreateDocumentDialog-DJ8c0WZb.js +0 -256
- package/studio/dom-to-image-more.min-D6jGGdrW.js +0 -877
- package/studio/rolldown-runtime-B0aSnxlc.js +0 -20
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { S as MarkdownNode, at as Locale, it as CollectionName, n as CmsMarkdownDocument, ot as RoutePattern } from "./models-VmGmG19-.js";
|
|
2
|
+
import { i as decodeManagedMediaReference, r as decodeAuthoredDocumentReference } from "./References-CCPDAPve.js";
|
|
3
|
+
import { r as FormCapabilities } from "./Forms-CfNPTiCr.js";
|
|
4
|
+
import { c as resolveCmsComarkAttributes, d as createCmsComarkRenderData, l as withCmsComarkProps, r as formStructureIssues, s as projectCmsEditorComponentAttributes } from "./Forms-CX-hwmJF.js";
|
|
5
|
+
import { a as createEditorNodeId, n as editorMetadata, o as editorNodeId } from "./metadata-UzZmjwxM.js";
|
|
5
6
|
import { Effect, Option, Predicate, Schema } from "effect";
|
|
6
7
|
import { Extension } from "@tiptap/core";
|
|
7
8
|
import { ySyncPluginKey } from "@tiptap/y-tiptap";
|
|
@@ -29,7 +30,7 @@ function finiteNumberAttribute(value, fallback) {
|
|
|
29
30
|
|
|
30
31
|
//#endregion
|
|
31
32
|
//#region ../document/src/internal/editor/image.ts
|
|
32
|
-
const isJsonObject$
|
|
33
|
+
const isJsonObject$3 = Schema.is(Schema.JsonObject);
|
|
33
34
|
const EditorImageLayout = Schema.Literals([
|
|
34
35
|
"natural",
|
|
35
36
|
"content",
|
|
@@ -71,7 +72,7 @@ function normalizeEditorImageLayout(value) {
|
|
|
71
72
|
return isEditorImageLayout(value) ? value : "natural";
|
|
72
73
|
}
|
|
73
74
|
function jsonObject$1(value) {
|
|
74
|
-
return isJsonObject$
|
|
75
|
+
return isJsonObject$3(value) ? value : {};
|
|
75
76
|
}
|
|
76
77
|
function stringValue(value) {
|
|
77
78
|
return Predicate.isString(value) || Predicate.isNumber(value) ? String(value) : "";
|
|
@@ -105,7 +106,7 @@ function isComarkMark(tag) {
|
|
|
105
106
|
|
|
106
107
|
//#endregion
|
|
107
108
|
//#region ../document/src/internal/comark/to-editor.ts
|
|
108
|
-
const isJsonObject$
|
|
109
|
+
const isJsonObject$2 = Schema.is(Schema.JsonObject);
|
|
109
110
|
const OPAQUE_BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
110
111
|
"math",
|
|
111
112
|
"table",
|
|
@@ -384,7 +385,7 @@ function elementChildren(node) {
|
|
|
384
385
|
return children;
|
|
385
386
|
}
|
|
386
387
|
function jsonObject(value) {
|
|
387
|
-
return isJsonObject$
|
|
388
|
+
return isJsonObject$2(value) ? value : {};
|
|
388
389
|
}
|
|
389
390
|
function mergeJsonAttributes(attributes, additions) {
|
|
390
391
|
return compactJsonAttributes(Object.assign({}, attributes, additions));
|
|
@@ -664,6 +665,181 @@ var EditorDocumentInvalid = class extends Schema.TaggedError()("EditorDocument.I
|
|
|
664
665
|
}) {};
|
|
665
666
|
var EditorRenderFailed = class extends Schema.TaggedError()("EditorDocument.RenderFailed", { cause: Schema.Defect() }) {};
|
|
666
667
|
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region ../document/src/StructuredFields.ts
|
|
670
|
+
function compileStructuredFields(definitions) {
|
|
671
|
+
const fields = new Map(definitions.map((field) => [field.name, field]));
|
|
672
|
+
if (fields.size !== definitions.length) throw new Error("Structured field names must be unique.");
|
|
673
|
+
for (const field of definitions) {
|
|
674
|
+
if (field.defaultValue === void 0) continue;
|
|
675
|
+
const issue = fieldIssue(field, field.defaultValue, "working");
|
|
676
|
+
if (issue) throw new Error(`Invalid default for ${field.label}: ${issue.message}`);
|
|
677
|
+
}
|
|
678
|
+
const listField = (name) => {
|
|
679
|
+
const field = fields.get(name);
|
|
680
|
+
if (!field || field.type !== "array" || field.input !== "list") throw new Error(`Structured field "${name}" is not a repeatable object.`);
|
|
681
|
+
return field;
|
|
682
|
+
};
|
|
683
|
+
const validateDetailed = (value, purpose) => {
|
|
684
|
+
const issues = [];
|
|
685
|
+
for (const name of Object.keys(value)) if (!fields.has(name)) issues.push({
|
|
686
|
+
message: `${name} is not editable.`,
|
|
687
|
+
path: [name]
|
|
688
|
+
});
|
|
689
|
+
for (const field of definitions) {
|
|
690
|
+
const issue = fieldIssue(field, value[field.name] ?? (value[field.name] === null ? null : field.defaultValue), purpose, [field.name]);
|
|
691
|
+
if (issue) issues.push(issue);
|
|
692
|
+
}
|
|
693
|
+
return issues;
|
|
694
|
+
};
|
|
695
|
+
return {
|
|
696
|
+
create: () => createObject(definitions),
|
|
697
|
+
set(current, name, value) {
|
|
698
|
+
const field = fields.get(name);
|
|
699
|
+
if (!field) throw new Error(`Structured field "${name}" is unavailable.`);
|
|
700
|
+
const issue = fieldIssue(field, value, "working");
|
|
701
|
+
if (issue) throw new Error(issue.message);
|
|
702
|
+
const next = Object.fromEntries(Object.entries(current));
|
|
703
|
+
if (value === void 0) delete next[name];
|
|
704
|
+
else next[name] = structuredClone(value);
|
|
705
|
+
return next;
|
|
706
|
+
},
|
|
707
|
+
validate: (value, purpose) => validateDetailed(value, purpose).map((issue) => issue.message),
|
|
708
|
+
validateDetailed,
|
|
709
|
+
validateIdentities: (value) => identityIssues(definitions, value),
|
|
710
|
+
createListItem(name) {
|
|
711
|
+
return createObject(listField(name).fields ?? [], true);
|
|
712
|
+
},
|
|
713
|
+
duplicateListItem(name, item) {
|
|
714
|
+
const field = listField(name);
|
|
715
|
+
const copied = cloneWithFreshIdentities(item, field.fields ?? []);
|
|
716
|
+
return Object.assign(createObject(field.fields ?? [], true), copied, { id: createEditorNodeId() });
|
|
717
|
+
},
|
|
718
|
+
moveListItem(items, id, offset) {
|
|
719
|
+
const index = items.findIndex((item) => item.id === id);
|
|
720
|
+
const target = index + offset;
|
|
721
|
+
if (index < 0 || target < 0 || target >= items.length) return items;
|
|
722
|
+
const next = [...items];
|
|
723
|
+
const item = next.splice(index, 1)[0];
|
|
724
|
+
if (!item) return items;
|
|
725
|
+
next.splice(target, 0, item);
|
|
726
|
+
return next;
|
|
727
|
+
},
|
|
728
|
+
removeListItem: (items, id) => items.filter((item) => item.id !== id)
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
function identityIssues(fields, value, parent = []) {
|
|
732
|
+
return fields.flatMap((field) => {
|
|
733
|
+
const current = value[field.name];
|
|
734
|
+
const path = [...parent, field.name];
|
|
735
|
+
if (field.type === "object" && isJsonObject$1(current)) return identityIssues(field.fields ?? [], current, path);
|
|
736
|
+
if (field.type !== "array" || !Array.isArray(current)) return [];
|
|
737
|
+
const seen = /* @__PURE__ */ new Set();
|
|
738
|
+
return current.flatMap((item, index) => {
|
|
739
|
+
if (!isJsonObject$1(item)) return [];
|
|
740
|
+
const id = item.id;
|
|
741
|
+
const issue = !Predicate.isString(id) || !id || seen.has(id) ? [{
|
|
742
|
+
message: `${field.label} items need unique identities.`,
|
|
743
|
+
path: [
|
|
744
|
+
...path,
|
|
745
|
+
index,
|
|
746
|
+
"id"
|
|
747
|
+
]
|
|
748
|
+
}] : [];
|
|
749
|
+
if (Predicate.isString(id) && id) seen.add(id);
|
|
750
|
+
return [...issue, ...identityIssues(field.fields ?? [], item, [...path, index])];
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
function createObject(fields, listItem = false) {
|
|
755
|
+
return {
|
|
756
|
+
...listItem ? { id: createEditorNodeId() } : void 0,
|
|
757
|
+
...Object.fromEntries(fields.flatMap((field) => field.required || field.defaultValue !== void 0 ? [[field.name, structuredClone(field.defaultValue ?? defaultValue(field))]] : []))
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
function defaultValue(field) {
|
|
761
|
+
if (field.type === "object") return createObject(field.fields ?? []);
|
|
762
|
+
if (field.type === "array") return [];
|
|
763
|
+
if (field.type === "string[]") return [];
|
|
764
|
+
if (field.type === "number") return 0;
|
|
765
|
+
if (field.type === "boolean") return false;
|
|
766
|
+
return field.options[0]?.value ?? "";
|
|
767
|
+
}
|
|
768
|
+
function cloneWithFreshIdentities(value, fields) {
|
|
769
|
+
const byName = new Map(fields.map((field) => [field.name, field]));
|
|
770
|
+
const copy = {};
|
|
771
|
+
for (const [name, child] of Object.entries(value)) {
|
|
772
|
+
if (name === "id") continue;
|
|
773
|
+
const field = byName.get(name);
|
|
774
|
+
if (field?.type === "object" && isJsonObject$1(child)) copy[name] = cloneWithFreshIdentities(child, field.fields ?? []);
|
|
775
|
+
else if (field?.type === "array" && Array.isArray(child)) copy[name] = child.map((item) => isJsonObject$1(item) ? Object.assign(cloneWithFreshIdentities(item, field.fields ?? []), { id: createEditorNodeId() }) : structuredClone(item));
|
|
776
|
+
else copy[name] = structuredClone(child);
|
|
777
|
+
}
|
|
778
|
+
return copy;
|
|
779
|
+
}
|
|
780
|
+
function fieldIssue(field, value, purpose, path = [field.name]) {
|
|
781
|
+
const issue = (message, issuePath = path) => ({
|
|
782
|
+
message,
|
|
783
|
+
path: issuePath
|
|
784
|
+
});
|
|
785
|
+
if (value === void 0) return field.required && purpose === "publish" ? issue(`${field.label} is required.`) : void 0;
|
|
786
|
+
if (value === null && field.nullable) return void 0;
|
|
787
|
+
if (!(field.type === "string" || field.type === "date" ? Predicate.isString(value) : field.type === "number" ? Predicate.isNumber(value) && Number.isFinite(value) : field.type === "boolean" ? Predicate.isBoolean(value) : field.type === "string[]" ? Array.isArray(value) && value.every(Predicate.isString) : field.type === "array" ? Array.isArray(value) : isJsonObject$1(value))) return issue(`${field.label} must be ${field.type}.`);
|
|
788
|
+
if (field.type === "object" || field.type === "array") {
|
|
789
|
+
const entries = Array.isArray(value) ? value : [value];
|
|
790
|
+
const ids = /* @__PURE__ */ new Set();
|
|
791
|
+
for (const [index, entry] of entries.entries()) {
|
|
792
|
+
const entryPath = field.type === "array" ? [...path, index] : path;
|
|
793
|
+
if (!isJsonObject$1(entry)) return issue(`${field.label} must contain objects.`, entryPath);
|
|
794
|
+
if (field.type === "array") {
|
|
795
|
+
const id = entry.id;
|
|
796
|
+
if (!Predicate.isString(id) || !id || ids.has(id)) return issue(`${field.label} items need unique identities.`, [...entryPath, "id"]);
|
|
797
|
+
ids.add(id);
|
|
798
|
+
}
|
|
799
|
+
for (const key of Object.keys(entry)) if (!(field.type === "array" && key === "id") && !field.fields?.some((child) => child.name === key)) return issue(`${field.label} contains an unavailable field.`, [...entryPath, key]);
|
|
800
|
+
for (const child of field.fields ?? []) {
|
|
801
|
+
const childIssue = fieldIssue(child, entry[child.name], purpose, [...entryPath, child.name]);
|
|
802
|
+
if (childIssue) return {
|
|
803
|
+
...childIssue,
|
|
804
|
+
message: `${field.label}: ${childIssue.message}`
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
if (purpose === "publish" && field.required && value === "" && [
|
|
810
|
+
"image",
|
|
811
|
+
"link",
|
|
812
|
+
"document",
|
|
813
|
+
"media"
|
|
814
|
+
].includes(field.input)) return issue(`${field.label} is required.`);
|
|
815
|
+
if (purpose === "publish" && Predicate.isString(value) && value && (field.input === "image" || field.input === "link") && !(field.input === "link" && decodeAuthoredDocumentReference(value)) && !validAuthoringUrl(value, field.input)) return issue(`${field.label} needs a valid ${field.input === "image" ? "image URL" : "link"}.`);
|
|
816
|
+
if (purpose === "publish" && Predicate.isString(value) && value && field.input === "document" && !decodeAuthoredDocumentReference(value)) return issue(`${field.label} needs a valid document reference.`);
|
|
817
|
+
if (purpose === "publish" && Predicate.isString(value) && value && field.input === "media" && !decodeManagedMediaReference(value)) return issue(`${field.label} needs a valid managed-media reference.`);
|
|
818
|
+
if (field.options.length) {
|
|
819
|
+
if ((Array.isArray(value) ? value : [value]).some((entry) => !field.options.some((option) => option.value === entry))) return issue(`${field.label} must use only available choices.`);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
function isJsonObject$1(value) {
|
|
823
|
+
return Schema.is(Schema.JsonObject)(value);
|
|
824
|
+
}
|
|
825
|
+
/** URL values remain ordinary strings; identity-backed references use dedicated field inputs. */
|
|
826
|
+
function validAuthoringUrl(value, input) {
|
|
827
|
+
if (value.trim() !== value || value.includes("\\")) return false;
|
|
828
|
+
for (const character of value) if (character.charCodeAt(0) <= 32) return false;
|
|
829
|
+
if (value.startsWith("/") && !value.startsWith("//")) return true;
|
|
830
|
+
if (input === "link" && value.startsWith("#")) return true;
|
|
831
|
+
try {
|
|
832
|
+
const url = new URL(value);
|
|
833
|
+
return [
|
|
834
|
+
"https:",
|
|
835
|
+
"http:",
|
|
836
|
+
...input === "link" ? ["mailto:", "tel:"] : []
|
|
837
|
+
].includes(url.protocol);
|
|
838
|
+
} catch {
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
667
843
|
//#endregion
|
|
668
844
|
//#region ../document/src/AuthoringSchema.ts
|
|
669
845
|
const parseAuthoringContent = Effect.fn("AuthoringSchema.parseContent")(function* (markdown) {
|
|
@@ -684,7 +860,7 @@ function collectionComponents(components, body) {
|
|
|
684
860
|
/** Configuration errors belong to developers, before an installation adopts the catalog. */
|
|
685
861
|
function validateCollectionBody(components, body) {
|
|
686
862
|
return [
|
|
687
|
-
...components.flatMap((component) => component.authoring.slots.flatMap((slot) => [...(slot.blocks ?? []).filter((name) => !components.some((candidate) => candidate.name === name)).map((name) => `Unknown block "${name}" in ${slot.label}.`), ...(slot.groups ?? []).filter((group) => !components.some((candidate) => candidate.authoring.group === group)).map((group) => `Unknown block group "${group}" in ${slot.label}.`)])),
|
|
863
|
+
...components.flatMap((component) => component.authoring.slots.flatMap((slot) => slot.input === "blocks" ? [...(slot.blocks ?? []).filter((name) => !components.some((candidate) => candidate.name === name)).map((name) => `Unknown block "${name}" in ${slot.label}.`), ...(slot.groups ?? []).filter((group) => !components.some((candidate) => candidate.authoring.group === group)).map((group) => `Unknown block group "${group}" in ${slot.label}.`)] : [])),
|
|
688
864
|
...(body?.blocks ?? []).filter((name) => !components.some((component) => component.name === name)).map((name) => `Unknown block "${name}".`),
|
|
689
865
|
...(body?.groups ?? []).filter((group) => !components.some((component) => component.authoring.group === group)).map((group) => `Unknown block group "${group}".`)
|
|
690
866
|
];
|
|
@@ -692,16 +868,28 @@ function validateCollectionBody(components, body) {
|
|
|
692
868
|
function contentIssues(node, schemas, allowed, purpose, collectionAllowed = allowed) {
|
|
693
869
|
const issues = [];
|
|
694
870
|
if (node.type === "cmsBlock") {
|
|
695
|
-
const name = String(node.attrs?.tag).toLowerCase();
|
|
871
|
+
const name = String(node.attrs?.tag ?? "unknown").toLowerCase() || "unknown";
|
|
696
872
|
const schema = schemas.get(name);
|
|
697
|
-
if (!schema) issues.push(
|
|
873
|
+
if (!schema) issues.push({
|
|
874
|
+
component: name,
|
|
875
|
+
message: "This block is unavailable. Ask your site developer to restore its definition."
|
|
876
|
+
});
|
|
698
877
|
else {
|
|
699
|
-
if (!allowed.has(name)) issues.push(
|
|
700
|
-
|
|
701
|
-
|
|
878
|
+
if (!allowed.has(name)) issues.push({
|
|
879
|
+
component: name,
|
|
880
|
+
message: `${schema.definition.label} is not allowed in this content region.`
|
|
881
|
+
});
|
|
882
|
+
issues.push(...schema.validateDetailed(node, purpose));
|
|
883
|
+
if (purpose === "publish" && schema.definition.form) issues.push(...formStructureIssues(node.attrs?.props?.steps, schema.definition.form, name).map((message) => ({
|
|
884
|
+
component: name,
|
|
885
|
+
message
|
|
886
|
+
})));
|
|
702
887
|
}
|
|
703
888
|
}
|
|
704
|
-
if (node.type === "cmsOpaque" || node.type === "cmsInlineOpaque") issues.push(
|
|
889
|
+
if (node.type === "cmsOpaque" || node.type === "cmsInlineOpaque") issues.push({
|
|
890
|
+
component: String(node.attrs?.tag ?? node.type),
|
|
891
|
+
message: "This content is unsupported. Ask your site developer to update it before publishing."
|
|
892
|
+
});
|
|
705
893
|
if (node.type === "cmsBlock") {
|
|
706
894
|
const schema = schemas.get(String(node.attrs?.tag).toLowerCase());
|
|
707
895
|
for (const region of node.content ?? []) {
|
|
@@ -726,18 +914,11 @@ function createAuthoringDocumentValidator(components) {
|
|
|
726
914
|
};
|
|
727
915
|
}
|
|
728
916
|
function createAuthoringSchema(name, definition) {
|
|
917
|
+
const structuredFields = compileStructuredFields(definition.props);
|
|
729
918
|
const fields = new Map(definition.props.map((field) => [field.name, field]));
|
|
730
919
|
const slots = new Map(definition.slots.map((slot) => [slot.name, slot]));
|
|
731
920
|
if (fields.size !== definition.props.length || slots.size !== definition.slots.length) throw new Error(`${definition.label}: authoring names must be unique.`);
|
|
732
|
-
const initialProps = {
|
|
733
|
-
...Object.fromEntries(definition.props.flatMap((field) => field.defaultValue === void 0 ? [] : [[field.name, field.defaultValue]])),
|
|
734
|
-
...definition.initialProps
|
|
735
|
-
};
|
|
736
|
-
for (const field of definition.props) {
|
|
737
|
-
if (field.defaultValue === void 0) continue;
|
|
738
|
-
const issue = propertyIssue(field, field.defaultValue, "working");
|
|
739
|
-
if (issue) throw new Error(`Invalid default for ${definition.label}: ${issue}`);
|
|
740
|
-
}
|
|
921
|
+
const initialProps = Object.assign({}, structuredFields.create(), definition.initialProps);
|
|
741
922
|
function createSlot(slotName) {
|
|
742
923
|
const slot = slots.get(slotName);
|
|
743
924
|
if (!slot) throw new Error(`${definition.label}: unknown content region ${slotName}.`);
|
|
@@ -767,81 +948,57 @@ function createAuthoringSchema(name, definition) {
|
|
|
767
948
|
content: definition.slots.filter((slot) => slot.required || slot.initial !== void 0).map((slot) => createSlot(slot.name))
|
|
768
949
|
};
|
|
769
950
|
}
|
|
770
|
-
function
|
|
951
|
+
function validateDetailed(node, purpose) {
|
|
771
952
|
const issues = [];
|
|
772
953
|
const attributes = node.attrs?.props;
|
|
773
954
|
const values = isJsonObject(attributes) ? attributes : {};
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
955
|
+
issues.push(...structuredFields.validateDetailed(values, purpose).map((issue) => ({
|
|
956
|
+
component: name,
|
|
957
|
+
field: issue.path,
|
|
958
|
+
message: issue.message
|
|
959
|
+
})));
|
|
779
960
|
const used = /* @__PURE__ */ new Set();
|
|
780
961
|
for (const region of node.content ?? []) {
|
|
781
962
|
const key = String(region.attrs?.name ?? "default");
|
|
782
963
|
const slot = slots.get(key);
|
|
783
964
|
if (!slot || region.type !== "cmsSlot") {
|
|
784
|
-
issues.push(
|
|
965
|
+
issues.push({
|
|
966
|
+
component: name,
|
|
967
|
+
message: `${definition.label}: unsupported content region ${key}.`
|
|
968
|
+
});
|
|
785
969
|
continue;
|
|
786
970
|
}
|
|
787
|
-
if (used.has(key)) issues.push(
|
|
971
|
+
if (used.has(key)) issues.push({
|
|
972
|
+
component: name,
|
|
973
|
+
message: `${slot.label} can only appear once.`
|
|
974
|
+
});
|
|
788
975
|
used.add(key);
|
|
789
|
-
if (!validRegion(slot, region.content ?? [])) issues.push(
|
|
976
|
+
if (!validRegion(slot, region.content ?? [])) issues.push({
|
|
977
|
+
component: name,
|
|
978
|
+
message: `${slot.label} contains unsupported formatting or blocks.`
|
|
979
|
+
});
|
|
790
980
|
}
|
|
791
|
-
for (const slot of definition.slots) if (slot.required && !used.has(slot.name)) issues.push(
|
|
981
|
+
for (const slot of definition.slots) if (slot.required && !used.has(slot.name)) issues.push({
|
|
982
|
+
component: name,
|
|
983
|
+
message: `${slot.label} is required.`
|
|
984
|
+
});
|
|
792
985
|
return issues;
|
|
793
986
|
}
|
|
987
|
+
const validate = (node, purpose) => validateDetailed(node, purpose).map((issue) => issue.message);
|
|
794
988
|
const schema = {
|
|
795
989
|
definition,
|
|
796
990
|
createContent,
|
|
797
991
|
createSlot,
|
|
798
992
|
validate,
|
|
993
|
+
validateDetailed,
|
|
799
994
|
setProperty(current, key, value) {
|
|
800
|
-
|
|
801
|
-
if (!field) throw new Error(`${definition.label}: ${key} is not editable.`);
|
|
802
|
-
const issue = propertyIssue(field, value, "working");
|
|
803
|
-
if (issue) throw new Error(issue);
|
|
804
|
-
const next = Object.fromEntries(Object.entries(current));
|
|
805
|
-
if (value === void 0) delete next[key];
|
|
806
|
-
else next[key] = value;
|
|
807
|
-
return next;
|
|
995
|
+
return structuredFields.set(current, key, value);
|
|
808
996
|
}
|
|
809
997
|
};
|
|
810
998
|
const issues = validate(createContent(), "publish");
|
|
811
999
|
if (issues.length) throw new Error(`Invalid initial content for ${definition.label}: ${issues.join(" ")}`);
|
|
812
1000
|
return schema;
|
|
813
1001
|
}
|
|
814
|
-
function propertyIssue(field, value, purpose) {
|
|
815
|
-
if (value === void 0) return field.required && purpose === "publish" ? `${field.label} is required.` : void 0;
|
|
816
|
-
if (value === null && field.nullable) return void 0;
|
|
817
|
-
let valid;
|
|
818
|
-
if (field.type === "string") valid = Predicate.isString(value);
|
|
819
|
-
else if (field.type === "number") valid = Predicate.isNumber(value) && Number.isFinite(value);
|
|
820
|
-
else if (field.type === "boolean") valid = Predicate.isBoolean(value);
|
|
821
|
-
else if (field.type === "array") valid = Array.isArray(value);
|
|
822
|
-
else valid = isJsonObject(value);
|
|
823
|
-
if (!valid) return `${field.label} must be ${field.type}.`;
|
|
824
|
-
if (field.type === "object" || field.type === "array") {
|
|
825
|
-
const entries = Array.isArray(value) ? value : [value];
|
|
826
|
-
const ids = /* @__PURE__ */ new Set();
|
|
827
|
-
for (const entry of entries) {
|
|
828
|
-
if (!isJsonObject(entry)) return `${field.label} must contain objects.`;
|
|
829
|
-
if (field.type === "array") {
|
|
830
|
-
const id = entry.id;
|
|
831
|
-
if (!Predicate.isString(id) || !id || ids.has(id)) return `${field.label} items need unique identities.`;
|
|
832
|
-
ids.add(id);
|
|
833
|
-
}
|
|
834
|
-
for (const key of Object.keys(entry)) if (!(field.type === "array" && key === "id") && !field.fields?.some((child) => child.name === key)) return `${field.label} contains an unavailable field.`;
|
|
835
|
-
for (const child of field.fields ?? []) {
|
|
836
|
-
const issue = propertyIssue(child, entry[child.name], purpose);
|
|
837
|
-
if (issue) return `${field.label}: ${issue}`;
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
if (purpose === "publish" && field.required && value === "" && (field.input === "image" || field.input === "link")) return `${field.label} is required.`;
|
|
842
|
-
if (purpose === "publish" && Predicate.isString(value) && value && (field.input === "image" || field.input === "link") && !validAuthoringUrl(value, field.input)) return `${field.label} needs a valid ${field.input === "image" ? "image URL" : "link"}.`;
|
|
843
|
-
if (field.options.length && !field.options.some((option) => option.value === value)) return `${field.label} must use one of its available choices.`;
|
|
844
|
-
}
|
|
845
1002
|
function validRegion(slot, content) {
|
|
846
1003
|
if (slot.input === "blocks") return content.every((node) => node.type === "cmsBlock" || node.type === "paragraph" && !node.content?.length);
|
|
847
1004
|
const types = /* @__PURE__ */ new Set([
|
|
@@ -850,86 +1007,130 @@ function validRegion(slot, content) {
|
|
|
850
1007
|
"hardBreak"
|
|
851
1008
|
]);
|
|
852
1009
|
const marks = /* @__PURE__ */ new Set();
|
|
853
|
-
if (slot.input
|
|
854
|
-
if (slot.input === "rich-text") for (const feature of slot.features) if (feature === "bullet-list") {
|
|
1010
|
+
if (slot.input !== "rich-text" && content.length > 1) return false;
|
|
1011
|
+
if (slot.input === "inline-text" || slot.input === "rich-text") for (const feature of slot.features) if (feature === "bullet-list") {
|
|
855
1012
|
types.add("bulletList");
|
|
856
1013
|
types.add("listItem");
|
|
857
1014
|
} else marks.add(feature);
|
|
858
1015
|
const valid = (node) => types.has(node.type ?? "") && (node.marks ?? []).every((mark) => marks.has(mark.type)) && (node.content ?? []).every(valid);
|
|
859
1016
|
return content.every(valid);
|
|
860
1017
|
}
|
|
861
|
-
/** URL values remain ordinary Vue strings and use the document model's public paths. */
|
|
862
|
-
function validAuthoringUrl(value, input) {
|
|
863
|
-
if (value.trim() !== value || value.includes("\\")) return false;
|
|
864
|
-
for (const character of value) if (character.charCodeAt(0) <= 32) return false;
|
|
865
|
-
if (value.startsWith("/") && !value.startsWith("//")) return true;
|
|
866
|
-
if (input === "link" && value.startsWith("#")) return true;
|
|
867
|
-
try {
|
|
868
|
-
const url = new URL(value);
|
|
869
|
-
return [
|
|
870
|
-
"https:",
|
|
871
|
-
"http:",
|
|
872
|
-
...input === "link" ? ["mailto:", "tel:"] : []
|
|
873
|
-
].includes(url.protocol);
|
|
874
|
-
} catch {
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
1018
|
|
|
879
1019
|
//#endregion
|
|
880
|
-
//#region ../protocol/src/
|
|
881
|
-
const
|
|
1020
|
+
//#region ../protocol/src/StructuredFields.ts
|
|
1021
|
+
const presentation = {
|
|
882
1022
|
name: Schema.NonEmptyString,
|
|
883
1023
|
label: Schema.NonEmptyString,
|
|
884
|
-
|
|
885
|
-
type: Schema.Literals([
|
|
886
|
-
"string",
|
|
887
|
-
"number",
|
|
888
|
-
"boolean",
|
|
889
|
-
"object",
|
|
890
|
-
"array"
|
|
891
|
-
]),
|
|
892
|
-
input: Schema.Literals([
|
|
893
|
-
"text",
|
|
894
|
-
"textarea",
|
|
895
|
-
"select",
|
|
896
|
-
"number",
|
|
897
|
-
"toggle",
|
|
898
|
-
"image",
|
|
899
|
-
"link",
|
|
900
|
-
"object",
|
|
901
|
-
"list"
|
|
902
|
-
]),
|
|
903
|
-
required: Schema.Boolean,
|
|
904
|
-
nullable: Schema.Boolean,
|
|
1024
|
+
description: Schema.optionalKey(Schema.String),
|
|
905
1025
|
defaultValue: Schema.optionalKey(Schema.Json),
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1026
|
+
required: Schema.Boolean,
|
|
1027
|
+
nullable: Schema.Boolean
|
|
1028
|
+
};
|
|
1029
|
+
const stringOptions = Schema.Array(Schema.Struct({
|
|
1030
|
+
value: Schema.String,
|
|
1031
|
+
label: Schema.String
|
|
1032
|
+
}));
|
|
1033
|
+
const numberOptions = Schema.Array(Schema.Struct({
|
|
1034
|
+
value: Schema.Finite,
|
|
1035
|
+
label: Schema.String
|
|
1036
|
+
}));
|
|
1037
|
+
const noOptions = Schema.Tuple([]);
|
|
1038
|
+
const StructuredField = Schema.Union([
|
|
1039
|
+
Schema.Struct({
|
|
1040
|
+
...presentation,
|
|
1041
|
+
type: Schema.tag("boolean"),
|
|
1042
|
+
input: Schema.Literal("toggle"),
|
|
1043
|
+
options: noOptions
|
|
1044
|
+
}),
|
|
1045
|
+
Schema.Struct({
|
|
1046
|
+
...presentation,
|
|
1047
|
+
type: Schema.tag("date"),
|
|
1048
|
+
input: Schema.Literal("date"),
|
|
1049
|
+
options: noOptions
|
|
1050
|
+
}),
|
|
1051
|
+
Schema.Struct({
|
|
1052
|
+
...presentation,
|
|
1053
|
+
type: Schema.tag("number"),
|
|
1054
|
+
input: Schema.Literals(["number", "select"]),
|
|
1055
|
+
options: numberOptions
|
|
1056
|
+
}),
|
|
1057
|
+
Schema.Struct({
|
|
1058
|
+
...presentation,
|
|
1059
|
+
type: Schema.tag("string"),
|
|
1060
|
+
input: Schema.Literals([
|
|
1061
|
+
"select",
|
|
1062
|
+
"text",
|
|
1063
|
+
"textarea",
|
|
1064
|
+
"image",
|
|
1065
|
+
"link",
|
|
1066
|
+
"document",
|
|
1067
|
+
"media"
|
|
1068
|
+
]),
|
|
1069
|
+
options: stringOptions
|
|
1070
|
+
}),
|
|
1071
|
+
Schema.Struct({
|
|
1072
|
+
...presentation,
|
|
1073
|
+
type: Schema.tag("string[]"),
|
|
1074
|
+
input: Schema.Literal("multiselect"),
|
|
1075
|
+
options: stringOptions
|
|
1076
|
+
}),
|
|
1077
|
+
Schema.Struct({
|
|
1078
|
+
...presentation,
|
|
1079
|
+
type: Schema.tag("object"),
|
|
1080
|
+
input: Schema.Literal("object"),
|
|
1081
|
+
options: noOptions,
|
|
1082
|
+
fields: Schema.Array(Schema.suspend(() => StructuredField))
|
|
1083
|
+
}),
|
|
1084
|
+
Schema.Struct({
|
|
1085
|
+
...presentation,
|
|
1086
|
+
type: Schema.tag("array"),
|
|
1087
|
+
input: Schema.Literal("list"),
|
|
1088
|
+
options: noOptions,
|
|
1089
|
+
fields: Schema.Array(Schema.suspend(() => StructuredField))
|
|
1090
|
+
})
|
|
1091
|
+
]);
|
|
1092
|
+
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region ../protocol/src/Authoring.ts
|
|
1095
|
+
const inlineTextFeature = Schema.Literals([
|
|
1096
|
+
"bold",
|
|
1097
|
+
"italic",
|
|
1098
|
+
"link",
|
|
1099
|
+
"code"
|
|
1100
|
+
]);
|
|
1101
|
+
const richTextFeature = Schema.Union([inlineTextFeature, Schema.Literal("bullet-list")]);
|
|
1102
|
+
const slotBase = {
|
|
913
1103
|
name: Schema.NonEmptyString,
|
|
914
1104
|
label: Schema.NonEmptyString,
|
|
915
1105
|
help: Schema.optionalKey(Schema.String),
|
|
916
1106
|
required: Schema.Boolean,
|
|
917
|
-
input: Schema.Literals([
|
|
918
|
-
"text",
|
|
919
|
-
"rich-text",
|
|
920
|
-
"blocks"
|
|
921
|
-
]),
|
|
922
|
-
blocks: Schema.optionalKey(Schema.Array(Schema.NonEmptyString)),
|
|
923
|
-
groups: Schema.optionalKey(Schema.Array(Schema.NonEmptyString)),
|
|
924
|
-
features: Schema.Array(Schema.Literals([
|
|
925
|
-
"bold",
|
|
926
|
-
"italic",
|
|
927
|
-
"link",
|
|
928
|
-
"bullet-list",
|
|
929
|
-
"code"
|
|
930
|
-
])),
|
|
931
1107
|
initial: Schema.optionalKey(Schema.Array(MarkdownNode))
|
|
932
|
-
}
|
|
1108
|
+
};
|
|
1109
|
+
const noFeatures = Schema.Tuple([]);
|
|
1110
|
+
const BlockSlot = Schema.Union([
|
|
1111
|
+
Schema.Struct({
|
|
1112
|
+
...slotBase,
|
|
1113
|
+
input: Schema.Literal("text"),
|
|
1114
|
+
features: noFeatures
|
|
1115
|
+
}),
|
|
1116
|
+
Schema.Struct({
|
|
1117
|
+
...slotBase,
|
|
1118
|
+
input: Schema.Literal("inline-text"),
|
|
1119
|
+
features: Schema.Array(inlineTextFeature)
|
|
1120
|
+
}),
|
|
1121
|
+
Schema.Struct({
|
|
1122
|
+
...slotBase,
|
|
1123
|
+
input: Schema.Literal("rich-text"),
|
|
1124
|
+
features: Schema.Array(richTextFeature)
|
|
1125
|
+
}),
|
|
1126
|
+
Schema.Struct({
|
|
1127
|
+
...slotBase,
|
|
1128
|
+
input: Schema.Literal("blocks"),
|
|
1129
|
+
features: noFeatures,
|
|
1130
|
+
blocks: Schema.optionalKey(Schema.Array(Schema.NonEmptyString)),
|
|
1131
|
+
groups: Schema.optionalKey(Schema.Array(Schema.NonEmptyString))
|
|
1132
|
+
})
|
|
1133
|
+
]);
|
|
933
1134
|
const BlockAuthoring = Schema.Struct({
|
|
934
1135
|
version: Schema.Literal(1),
|
|
935
1136
|
form: Schema.optionalKey(FormCapabilities),
|
|
@@ -937,73 +1138,30 @@ const BlockAuthoring = Schema.Struct({
|
|
|
937
1138
|
description: Schema.optionalKey(Schema.String),
|
|
938
1139
|
group: Schema.optionalKey(Schema.String),
|
|
939
1140
|
icon: Schema.optionalKey(Schema.String),
|
|
940
|
-
props: Schema.Array(
|
|
1141
|
+
props: Schema.Array(StructuredField),
|
|
941
1142
|
slots: Schema.Array(BlockSlot),
|
|
942
1143
|
initialProps: Schema.JsonObject
|
|
943
1144
|
});
|
|
944
1145
|
|
|
945
1146
|
//#endregion
|
|
946
1147
|
//#region ../protocol/src/Configuration.ts
|
|
947
|
-
const fieldPresentation = {
|
|
948
|
-
path: Schema.NonEmptyString,
|
|
949
|
-
label: Schema.NonEmptyString,
|
|
950
|
-
description: Schema.optionalKey(Schema.String),
|
|
951
|
-
defaultValue: Schema.optionalKey(Schema.Json),
|
|
952
|
-
required: Schema.Boolean
|
|
953
|
-
};
|
|
954
|
-
const BooleanAuthoringField = Schema.Struct({
|
|
955
|
-
type: Schema.tag("boolean"),
|
|
956
|
-
...fieldPresentation,
|
|
957
|
-
input: Schema.Literal("toggle")
|
|
958
|
-
});
|
|
959
|
-
const DateAuthoringField = Schema.Struct({
|
|
960
|
-
type: Schema.tag("date"),
|
|
961
|
-
...fieldPresentation,
|
|
962
|
-
input: Schema.Literal("date")
|
|
963
|
-
});
|
|
964
|
-
const NumberAuthoringField = Schema.Struct({
|
|
965
|
-
type: Schema.tag("number"),
|
|
966
|
-
...fieldPresentation,
|
|
967
|
-
input: Schema.Literals(["number", "select"]),
|
|
968
|
-
options: Schema.Array(Schema.Finite)
|
|
969
|
-
});
|
|
970
|
-
const StringAuthoringField = Schema.Struct({
|
|
971
|
-
type: Schema.tag("string"),
|
|
972
|
-
...fieldPresentation,
|
|
973
|
-
input: Schema.Literals([
|
|
974
|
-
"select",
|
|
975
|
-
"text",
|
|
976
|
-
"textarea"
|
|
977
|
-
]),
|
|
978
|
-
options: Schema.Array(Schema.String)
|
|
979
|
-
});
|
|
980
|
-
const StringArrayAuthoringField = Schema.Struct({
|
|
981
|
-
type: Schema.tag("string[]"),
|
|
982
|
-
...fieldPresentation,
|
|
983
|
-
input: Schema.Literal("multiselect"),
|
|
984
|
-
options: Schema.Array(Schema.String)
|
|
985
|
-
});
|
|
986
|
-
const DocumentField = Schema.Union([
|
|
987
|
-
BooleanAuthoringField,
|
|
988
|
-
DateAuthoringField,
|
|
989
|
-
NumberAuthoringField,
|
|
990
|
-
StringArrayAuthoringField,
|
|
991
|
-
StringAuthoringField
|
|
992
|
-
]);
|
|
993
1148
|
const CollectionBody = Schema.Struct({
|
|
994
1149
|
blocks: Schema.optionalKey(Schema.Array(Schema.NonEmptyString)),
|
|
995
1150
|
groups: Schema.optionalKey(Schema.Array(Schema.NonEmptyString))
|
|
996
1151
|
});
|
|
1152
|
+
const CollectionRoutes = Schema.Struct({
|
|
1153
|
+
home: RoutePattern,
|
|
1154
|
+
entry: RoutePattern
|
|
1155
|
+
}).annotate({ identifier: "CollectionRoutes" });
|
|
997
1156
|
const CollectionDefinition = Schema.Struct({
|
|
998
1157
|
collection: CollectionName,
|
|
999
1158
|
body: Schema.optionalKey(CollectionBody),
|
|
1000
1159
|
label: Schema.NonEmptyString,
|
|
1001
1160
|
description: Schema.String,
|
|
1002
|
-
|
|
1003
|
-
addressPattern: AddressPattern,
|
|
1161
|
+
routes: CollectionRoutes,
|
|
1004
1162
|
hierarchy: Schema.Boolean,
|
|
1005
1163
|
canCreate: Schema.Boolean,
|
|
1006
|
-
authoringFields: Schema.Array(
|
|
1164
|
+
authoringFields: Schema.Array(StructuredField)
|
|
1007
1165
|
}).annotate({ identifier: "CollectionDefinition" });
|
|
1008
1166
|
const LocaleConfiguration = Schema.Struct({
|
|
1009
1167
|
locales: Schema.Array(Locale),
|
|
@@ -1029,5 +1187,5 @@ const MediaConfiguration = Schema.Struct({
|
|
|
1029
1187
|
});
|
|
1030
1188
|
|
|
1031
1189
|
//#endregion
|
|
1032
|
-
export {
|
|
1033
|
-
//# sourceMappingURL=Configuration-
|
|
1190
|
+
export { compactJsonAttributes as C, normalizeEditorImageLayout as S, nonEmptyStringAttribute as T, EDITOR_MARK_TYPES as _, BlockAuthoring as a, EDITOR_IMAGE_LAYOUT_ATTRIBUTE as b, parseAuthoringContent as c, EditorDocumentInvalid as d, EditorRenderFailed as f, comarkToEditor as g, SOURCE_MAPPINGS_META_KEY as h, MediaConfiguration as i, validateCollectionBody as l, createDocumentParser as m, ComponentDefinition as n, createAuthoringDocumentValidator as o, DOCUMENT_ENGINE_FINGERPRINT as p, DocumentConfiguration as r, createAuthoringSchema as s, AuthoringCatalog as t, compileStructuredFields as u, comarkTagForEditorMark as v, finiteNumberAttribute as w, encodeEditorImageAttributes as x, isEditorMark as y };
|
|
1191
|
+
//# sourceMappingURL=Configuration-JQ1qyaU0.js.map
|