@phtngyn/cms 0.1.0-beta.5 → 0.2.0-beta.1

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.
Files changed (93) hide show
  1. package/README.md +85 -5
  2. package/package.json +11 -1
  3. package/src/ApplicationTypes.d.ts +82 -0
  4. package/src/ApplicationTypes.js +1 -0
  5. package/src/{Configuration-CDMYfTre.js → Configuration-CjVUBBwa.js} +3 -3
  6. package/src/{Configuration-CDMYfTre.js.map → Configuration-CjVUBBwa.js.map} +1 -1
  7. package/src/Configuration.d.ts +9 -4
  8. package/src/Configuration.js.map +1 -1
  9. package/src/Content.d.ts +67 -0
  10. package/src/Content.js +291 -0
  11. package/src/Content.js.map +1 -0
  12. package/src/ContentTransfer-CRQet3QJ.d.ts +48 -0
  13. package/src/{ContentTransfer-C3Av9sWz.js → ContentTransfer-CTzGGKFV.js} +8 -4
  14. package/src/ContentTransfer-CTzGGKFV.js.map +1 -0
  15. package/src/{DocumentEngine-J7g-emdf.js → DocumentEngine-BbhfnTAc.js} +4 -4
  16. package/src/{DocumentEngine-J7g-emdf.js.map → DocumentEngine-BbhfnTAc.js.map} +1 -1
  17. package/src/DocumentModel.d.ts +8 -1
  18. package/src/DocumentModel.js +29 -2
  19. package/src/DocumentModel.js.map +1 -1
  20. package/src/{Forms-Dj6NuW66.js → Forms-02-p8qEw.js} +2 -2
  21. package/src/{Forms-Dj6NuW66.js.map → Forms-02-p8qEw.js.map} +1 -1
  22. package/src/{Forms-BsJMev5_.d.ts → Forms-BorTcIlp.d.ts} +2 -5
  23. package/src/Forms.d.ts +25 -14
  24. package/src/Forms.js.map +1 -1
  25. package/src/I18n-BXlVunfa.d.ts +27 -0
  26. package/src/I18n.d.ts +2 -20
  27. package/src/Module.js +14 -5
  28. package/src/Module.js.map +1 -1
  29. package/src/{S3MediaObjects-CpPSzJto.js → S3MediaObjects-DC0c8sYC.js} +54 -35
  30. package/src/{S3MediaObjects-CpPSzJto.js.map → S3MediaObjects-DC0c8sYC.js.map} +1 -1
  31. package/src/cli/content.js +63 -221
  32. package/src/cli/content.js.map +1 -1
  33. package/src/cli.js +93 -4
  34. package/src/cli.js.map +1 -1
  35. package/src/{connection-CBAy2qGy.js → connection-BPf4BQUZ.js} +2 -2
  36. package/src/{connection-CBAy2qGy.js.map → connection-BPf4BQUZ.js.map} +1 -1
  37. package/src/dev-lifecycle-vQLxwCFq.js +428 -0
  38. package/src/dev-lifecycle-vQLxwCFq.js.map +1 -0
  39. package/src/{installation-CNfIriVm.js → installation-DsGst1BH.js} +578 -457
  40. package/src/installation-DsGst1BH.js.map +1 -0
  41. package/src/internal/application-types.js +43 -0
  42. package/src/internal/application-types.js.map +1 -0
  43. package/src/internal/authoring-catalog.js +9 -4
  44. package/src/internal/authoring-catalog.js.map +1 -1
  45. package/src/internal/authoring-metadata.js +1 -1
  46. package/src/internal/configuration.js +10 -6
  47. package/src/internal/configuration.js.map +1 -1
  48. package/src/internal/dev-lifecycle.js +3 -0
  49. package/src/internal/document-model.js +2 -2
  50. package/src/internal/document-model.js.map +1 -1
  51. package/src/internal/i18n.js +21 -0
  52. package/src/internal/i18n.js.map +1 -1
  53. package/src/{location-BTqdfIzX.js → location-BgYhXEZp.js} +2 -2
  54. package/src/{location-BTqdfIzX.js.map → location-BgYhXEZp.js.map} +1 -1
  55. package/src/{models-Bah5B3bT.js → models-DgkGTFus.js} +6 -1
  56. package/src/models-DgkGTFus.js.map +1 -0
  57. package/src/{models-B4IoTmp7.js → models-k2nXyD6q.js} +2 -2
  58. package/src/{models-B4IoTmp7.js.map → models-k2nXyD6q.js.map} +1 -1
  59. package/src/runtime/delivery/context.js +1 -1
  60. package/src/runtime/delivery/plugin.js +27 -5
  61. package/src/runtime/delivery/plugin.js.map +1 -1
  62. package/src/runtime/delivery/preview.d.ts +1 -1
  63. package/src/runtime/delivery/types.d.ts +2 -85
  64. package/src/runtime/delivery/useCmsDocumentSeo.d.ts +8 -1
  65. package/src/runtime/delivery/useCmsDocumentSeo.js +19 -7
  66. package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
  67. package/src/runtime/delivery/useDocument.d.ts +2 -2
  68. package/src/runtime/delivery/useDocument.js.map +1 -1
  69. package/src/runtime/delivery/useDocumentQuery.d.ts +3 -3
  70. package/src/runtime/delivery/useDocumentQuery.js.map +1 -1
  71. package/src/runtime/forms/document.js +1 -1
  72. package/src/runtime/forms/useCmsForm.js +81 -41
  73. package/src/runtime/forms/useCmsForm.js.map +1 -1
  74. package/src/runtime/i18n/useCmsI18n.d.ts +9 -7
  75. package/src/runtime/i18n/useCmsI18n.js +5 -4
  76. package/src/runtime/i18n/useCmsI18n.js.map +1 -1
  77. package/src/runtime/installation.js +2 -2
  78. package/src/runtime/plugin.js +1 -1
  79. package/src/runtime/preview/connection.js +1 -1
  80. package/src/runtime/preview/controller.js +2 -2
  81. package/src/runtime/preview/plugin.client.js +3 -3
  82. package/src/runtime/preview/store.js +1 -1
  83. package/src/runtime/sitemap.js +1 -1
  84. package/src/scalars-CA6kyipS.d.ts +7 -0
  85. package/src/{store-b2CSXgMt.js → store-BYgSt7E3.js} +3 -3
  86. package/src/{store-b2CSXgMt.js.map → store-BYgSt7E3.js.map} +1 -1
  87. package/src/types-DutFRtaG.d.ts +90 -0
  88. package/studio/{CreateDocumentDialog-GGey1uBc.js → CreateDocumentDialog-BdiM77bb.js} +1 -1
  89. package/studio/{documentPlanning-DRErYmBU.js → documentPlanning-B7fyUj9r.js} +7072 -7065
  90. package/studio/host.js +2 -2
  91. package/src/ContentTransfer-C3Av9sWz.js.map +0 -1
  92. package/src/installation-CNfIriVm.js.map +0 -1
  93. package/src/models-Bah5B3bT.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { i as FormResult } from "../../Forms-CfcI3tPU.js";
2
- import { i as validateFormValues } from "../../Forms-Dj6NuW66.js";
3
1
  import { a as CMS_FORM_SUBMIT_PATH } from "../../HttpPaths-c9nLZ9H2.js";
2
+ import { i as FormResult } from "../../Forms-CfcI3tPU.js";
3
+ import { i as validateFormValues } from "../../Forms-02-p8qEw.js";
4
4
  import { Result, Schema } from "effect";
5
5
  import { computed, getCurrentInstance, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, useId, watch } from "vue";
6
6
 
@@ -17,23 +17,26 @@ function useCmsForm(input, options = {}) {
17
17
  const currentStep = computed(() => steps.value[stepIndex.value]);
18
18
  const isFirstStep = computed(() => stepIndex.value === 0);
19
19
  const isLastStep = computed(() => stepIndex.value === steps.value.length - 1);
20
- const isSubmitting = ref(false);
20
+ const submitting = ref(false);
21
21
  const isSuccess = ref(false);
22
22
  const isPreview = computed(() => definition.value.preview);
23
- const error = shallowRef();
23
+ const submitError = shallowRef();
24
+ const touched = ref(/* @__PURE__ */ new Set());
25
+ const controllers = /* @__PURE__ */ new Map();
24
26
  let controller;
25
27
  let generation = 0;
26
28
  let previousFields = /* @__PURE__ */ new Map();
27
29
  const stop = watch(definition, (next, before) => {
28
30
  generation++;
29
31
  controller?.abort();
30
- isSubmitting.value = false;
32
+ submitting.value = false;
31
33
  const sameForm = before?.documentId === next.documentId && JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) && before.name === next.name;
32
34
  values.value = Object.fromEntries(next.steps.flatMap((step) => step.fields).map((field) => [field.id, sameForm && previousFields.get(field.id) === field.type ? values.value[field.id] ?? null : field.type === "checkbox" ? false : field.type === "number" ? null : ""]));
33
35
  previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]));
34
36
  stepIndex.value = Math.max(0, next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id));
35
37
  errors.value = {};
36
- error.value = void 0;
38
+ touched.value = /* @__PURE__ */ new Set();
39
+ submitError.value = void 0;
37
40
  isSuccess.value = false;
38
41
  }, {
39
42
  immediate: true,
@@ -41,41 +44,71 @@ function useCmsForm(input, options = {}) {
41
44
  flush: "sync"
42
45
  });
43
46
  function validate() {
47
+ touched.value = new Set(fields.value.map((field) => field.id));
44
48
  errors.value = validateFormValues(fields.value, values.value);
45
49
  return Object.keys(errors.value).length === 0;
46
50
  }
47
- function fieldState(field) {
48
- const id = `${fieldIdPrefix}-${encodeURIComponent(field.id)}`;
49
- return {
50
- field,
51
- get value() {
52
- return values.value[field.id] ?? emptyFormValue(field);
53
- },
54
- get error() {
55
- return errors.value[field.id];
56
- },
57
- helpId: `${id}-help`,
58
- errorId: `${id}-error`,
59
- get inputAttrs() {
60
- const error = errors.value[field.id];
61
- const invalid = error ? "true" : void 0;
62
- const describedBy = [field.help ? `${id}-help` : void 0, error ? `${id}-error` : void 0].filter((part) => part !== void 0).join(" ");
51
+ function field(input) {
52
+ const fieldId = Schema.is(Schema.String)(input) ? input : input.id;
53
+ const existing = controllers.get(fieldId);
54
+ if (existing) return existing;
55
+ if (!fields.value.some((candidate) => candidate.id === fieldId)) throw new Error(`Unknown CMS form field ${fieldId}.`);
56
+ const current = computed(() => {
57
+ const candidate = fields.value.find((field) => field.id === fieldId);
58
+ if (!candidate) throw new Error(`CMS form field ${fieldId} no longer exists.`);
59
+ return candidate;
60
+ });
61
+ const controlId = `${fieldIdPrefix}-${encodeURIComponent(fieldId)}`;
62
+ const helpId = `${controlId}-help`;
63
+ const errorId = `${controlId}-error`;
64
+ const refreshError = () => {
65
+ const issue = validateFormValues([current.value], values.value)[fieldId];
66
+ const nextErrors = { ...errors.value };
67
+ if (issue) nextErrors[fieldId] = issue;
68
+ else delete nextErrors[fieldId];
69
+ errors.value = nextErrors;
70
+ };
71
+ const controller = {
72
+ field: current,
73
+ value: computed({
74
+ get: () => values.value[fieldId] ?? emptyFormValue(current.value),
75
+ set: (value) => {
76
+ values.value[fieldId] = normalizeFormValue(current.value, value);
77
+ if (touched.value.has(fieldId) || errors.value[fieldId]) refreshError();
78
+ }
79
+ }),
80
+ dirty: computed(() => values.value[fieldId] !== emptyFormValue(current.value)),
81
+ touched: computed(() => touched.value.has(fieldId)),
82
+ valid: computed(() => validateFormValues([current.value], values.value)[fieldId] === void 0),
83
+ errors: computed(() => errors.value[fieldId] ? [errors.value[fieldId]] : []),
84
+ controlAttrs: computed(() => {
85
+ const fieldError = errors.value[fieldId];
86
+ const describedBy = [current.value.help ? helpId : void 0, fieldError ? errorId : void 0].filter((part) => part !== void 0).join(" ");
63
87
  return {
64
- id,
65
- name: field.id,
66
- required: field.required === true,
67
- "aria-invalid": invalid,
88
+ id: controlId,
89
+ name: fieldId,
90
+ required: current.value.required === true,
91
+ "aria-invalid": fieldError ? "true" : void 0,
68
92
  "aria-describedby": describedBy || void 0
69
93
  };
94
+ }),
95
+ helpAttrs: { id: helpId },
96
+ errorAttrs: {
97
+ id: errorId,
98
+ role: "alert"
70
99
  },
71
- setValue: (value) => {
72
- values.value[field.id] = normalizeFormValue(field, value);
100
+ touch: () => {
101
+ touched.value = /* @__PURE__ */ new Set([...touched.value, fieldId]);
102
+ refreshError();
73
103
  }
74
104
  };
105
+ controllers.set(fieldId, controller);
106
+ return controller;
75
107
  }
76
108
  function next() {
77
- if (isSubmitting.value || isLastStep.value) return false;
109
+ if (submitting.value || isLastStep.value) return false;
78
110
  const stepFields = currentStep.value?.fields ?? [];
111
+ touched.value = /* @__PURE__ */ new Set([...touched.value, ...stepFields.map((field) => field.id)]);
79
112
  const issues = validateFormValues(stepFields, values.value);
80
113
  errors.value = {
81
114
  ...Object.fromEntries(Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id))),
@@ -86,21 +119,22 @@ function useCmsForm(input, options = {}) {
86
119
  return true;
87
120
  }
88
121
  function previous() {
89
- if (!isSubmitting.value && !isFirstStep.value) stepIndex.value--;
122
+ if (!submitting.value && !isFirstStep.value) stepIndex.value--;
90
123
  }
91
124
  function reset() {
92
125
  generation++;
93
126
  controller?.abort();
94
- isSubmitting.value = false;
127
+ submitting.value = false;
95
128
  values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]));
96
129
  errors.value = {};
97
- error.value = void 0;
130
+ touched.value = /* @__PURE__ */ new Set();
131
+ submitError.value = void 0;
98
132
  isSuccess.value = false;
99
133
  stepIndex.value = 0;
100
134
  }
101
135
  async function submit() {
102
- if (isSubmitting.value || isSuccess.value) return false;
103
- error.value = void 0;
136
+ if (submitting.value || isSuccess.value) return false;
137
+ submitError.value = void 0;
104
138
  if (!validate()) {
105
139
  stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
106
140
  return false;
@@ -111,7 +145,7 @@ function useCmsForm(input, options = {}) {
111
145
  }
112
146
  const currentGeneration = ++generation;
113
147
  controller = new AbortController();
114
- isSubmitting.value = true;
148
+ submitting.value = true;
115
149
  try {
116
150
  const { documentId, nodePath, revision } = definition.value;
117
151
  const result = await (options.submit ?? send)({
@@ -124,13 +158,13 @@ function useCmsForm(input, options = {}) {
124
158
  errors.value = { ...result.errors };
125
159
  isSuccess.value = result.status === "accepted";
126
160
  if (result.status === "invalid") stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
127
- if (result.status !== "accepted" && result.status !== "invalid") error.value = result.status === "stale" ? "This form has changed. Reload the page before submitting." : "Submission failed. Please try again.";
161
+ if (result.status !== "accepted" && result.status !== "invalid") submitError.value = result.status === "stale" ? "This form has changed. Reload the page before submitting." : "Submission failed. Please try again.";
128
162
  return isSuccess.value;
129
163
  } catch {
130
- if (generation === currentGeneration) error.value = "Submission failed. Please try again.";
164
+ if (generation === currentGeneration) submitError.value = "Submission failed. Please try again.";
131
165
  return false;
132
166
  } finally {
133
- if (generation === currentGeneration) isSubmitting.value = false;
167
+ if (generation === currentGeneration) submitting.value = false;
134
168
  }
135
169
  }
136
170
  if (getCurrentScope()) onScopeDispose(() => {
@@ -138,6 +172,9 @@ function useCmsForm(input, options = {}) {
138
172
  controller?.abort();
139
173
  stop();
140
174
  });
175
+ const invalidFields = computed(() => fields.value.map((entry) => field(entry)).filter((entry) => !entry.valid.value));
176
+ const firstInvalidFieldId = computed(() => invalidFields.value[0]?.controlAttrs.value.id);
177
+ const canSubmit = computed(() => !submitting.value && !isSuccess.value && invalidFields.value.length === 0);
141
178
  return {
142
179
  fields,
143
180
  steps,
@@ -147,11 +184,14 @@ function useCmsForm(input, options = {}) {
147
184
  stepIndex: readonly(stepIndex),
148
185
  isFirstStep,
149
186
  isLastStep,
150
- isSubmitting: readonly(isSubmitting),
187
+ submitting: readonly(submitting),
151
188
  isSuccess: readonly(isSuccess),
152
189
  isPreview,
153
- error: readonly(error),
154
- fieldState,
190
+ submitError: readonly(submitError),
191
+ canSubmit,
192
+ invalidFields,
193
+ firstInvalidFieldId,
194
+ field,
155
195
  next,
156
196
  previous,
157
197
  validate,
@@ -1 +1 @@
1
- {"version":3,"file":"useCmsForm.js","names":[],"sources":["../../../../../src/runtime/forms/useCmsForm.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ComputedRef } from 'vue'\nimport type { FormDefinition, FormField, FormStep, FormSubmission, FormValues } from '@internal/protocol/Forms'\nimport { FormResult } from '@internal/protocol/Forms'\nimport { validateFormValues } from '@internal/document/Forms'\nimport { Result, Schema } from 'effect'\nimport {\n computed,\n getCurrentInstance,\n getCurrentScope,\n onScopeDispose,\n readonly,\n ref,\n shallowRef,\n toValue,\n useId,\n watch,\n} from 'vue'\nimport { CMS_FORM_SUBMIT_PATH } from '@internal/protocol/HttpPaths'\n\nexport interface UseCmsFormOptions {\n /** Replace the HTTP transport, retaining validation and submission state. */\n readonly submit?: (submission: FormSubmission, signal: AbortSignal) => Promise<FormResult>\n}\n\nexport interface CmsFormFieldState {\n readonly field: FormField\n readonly value: FormValues[string]\n readonly error: string | undefined\n readonly helpId: string\n readonly errorId: string\n readonly inputAttrs: {\n readonly id: string\n readonly name: string\n readonly required: boolean\n readonly 'aria-invalid': 'true' | undefined\n readonly 'aria-describedby': string | undefined\n }\n readonly setValue: (value: FormValues[string] | undefined) => void\n}\n\nexport interface UseCmsFormReturn {\n readonly fields: ComputedRef<ReadonlyArray<FormField>>\n readonly steps: ComputedRef<ReadonlyArray<FormStep>>\n readonly values: Ref<Record<string, FormValues[string]>>\n readonly errors: Readonly<Ref<Readonly<Record<string, string>>>>\n readonly currentStep: ComputedRef<FormStep | undefined>\n readonly stepIndex: Readonly<Ref<number>>\n readonly isFirstStep: ComputedRef<boolean>\n readonly isLastStep: ComputedRef<boolean>\n readonly isSubmitting: Readonly<Ref<boolean>>\n readonly isSuccess: Readonly<Ref<boolean>>\n readonly isPreview: ComputedRef<boolean>\n readonly error: Readonly<Ref<string | undefined>>\n readonly fieldState: (field: FormField) => CmsFormFieldState\n readonly next: () => boolean\n readonly previous: () => void\n readonly validate: () => boolean\n readonly submit: () => Promise<boolean>\n readonly reset: () => void\n}\n\n/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */\nexport function useCmsForm(input: MaybeRefOrGetter<FormDefinition>, options: UseCmsFormOptions = {}): UseCmsFormReturn {\n const fieldIdPrefix = getCurrentInstance() ? useId() : 'cms-form'\n const definition = computed(() => toValue(input))\n const steps = computed(() => definition.value.steps)\n const fields = computed(() => steps.value.flatMap((step) => step.fields))\n const values = ref<Record<string, FormValues[string]>>({})\n const errors = shallowRef<Record<string, string>>({})\n const stepIndex = ref(0)\n const currentStep = computed(() => steps.value[stepIndex.value])\n const isFirstStep = computed(() => stepIndex.value === 0)\n const isLastStep = computed(() => stepIndex.value === steps.value.length - 1)\n const isSubmitting = ref(false)\n const isSuccess = ref(false)\n const isPreview = computed(() => definition.value.preview)\n const error = shallowRef<string>()\n let controller: AbortController | undefined\n let generation = 0\n let previousFields = new Map<string, string>()\n\n const stop = watch(\n definition,\n (next, before) => {\n generation++\n controller?.abort()\n isSubmitting.value = false\n\n const sameForm =\n before?.documentId === next.documentId &&\n JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) &&\n before.name === next.name\n\n values.value = Object.fromEntries(\n next.steps\n .flatMap((step) => step.fields)\n .map((field) => [\n field.id,\n sameForm && previousFields.get(field.id) === field.type\n ? (values.value[field.id] ?? null)\n : field.type === 'checkbox'\n ? false\n : field.type === 'number'\n ? null\n : '',\n ]),\n )\n previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]))\n stepIndex.value = Math.max(\n 0,\n next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id),\n )\n errors.value = {}\n error.value = undefined\n isSuccess.value = false\n },\n { immediate: true, deep: true, flush: 'sync' },\n )\n\n function validate(): boolean {\n errors.value = validateFormValues(fields.value, values.value)\n\n return Object.keys(errors.value).length === 0\n }\n\n function fieldState(field: FormField): CmsFormFieldState {\n const id = `${fieldIdPrefix}-${encodeURIComponent(field.id)}`\n\n return {\n field,\n get value() {\n return values.value[field.id] ?? emptyFormValue(field)\n },\n get error() {\n return errors.value[field.id]\n },\n helpId: `${id}-help`,\n errorId: `${id}-error`,\n get inputAttrs() {\n const error = errors.value[field.id]\n const invalid: 'true' | undefined = error ? 'true' : undefined\n\n const describedBy = [field.help ? `${id}-help` : undefined, error ? `${id}-error` : undefined]\n .filter((part) => part !== undefined)\n .join(' ')\n\n return {\n id,\n name: field.id,\n required: field.required === true,\n 'aria-invalid': invalid,\n 'aria-describedby': describedBy || undefined,\n }\n },\n setValue: (value) => {\n values.value[field.id] = normalizeFormValue(field, value)\n },\n }\n }\n\n function next(): boolean {\n if (isSubmitting.value || isLastStep.value) return false\n const stepFields = currentStep.value?.fields ?? []\n const issues = validateFormValues(stepFields, values.value)\n errors.value = {\n ...Object.fromEntries(\n Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id)),\n ),\n ...issues,\n }\n\n if (Object.keys(issues).length) return false\n stepIndex.value++\n\n return true\n }\n\n function previous(): void {\n if (!isSubmitting.value && !isFirstStep.value) stepIndex.value--\n }\n\n function reset(): void {\n generation++\n controller?.abort()\n isSubmitting.value = false\n values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]))\n errors.value = {}\n error.value = undefined\n isSuccess.value = false\n stepIndex.value = 0\n }\n\n async function submit(): Promise<boolean> {\n if (isSubmitting.value || isSuccess.value) return false\n error.value = undefined\n\n if (!validate()) {\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n return false\n }\n\n if (isPreview.value) {\n isSuccess.value = true\n\n return true\n }\n\n const currentGeneration = ++generation\n controller = new AbortController()\n isSubmitting.value = true\n\n try {\n const { documentId, nodePath, revision } = definition.value\n\n const result = await (options.submit ?? send)(\n { documentId, nodePath, revision, values: { ...values.value } },\n controller.signal,\n )\n\n if (generation !== currentGeneration) return false\n errors.value = { ...result.errors }\n isSuccess.value = result.status === 'accepted'\n\n if (result.status === 'invalid')\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n if (result.status !== 'accepted' && result.status !== 'invalid')\n error.value =\n result.status === 'stale'\n ? 'This form has changed. Reload the page before submitting.'\n : 'Submission failed. Please try again.'\n\n return isSuccess.value\n } catch {\n if (generation === currentGeneration) error.value = 'Submission failed. Please try again.'\n\n return false\n } finally {\n if (generation === currentGeneration) isSubmitting.value = false\n }\n }\n\n if (getCurrentScope())\n onScopeDispose(() => {\n generation++\n controller?.abort()\n stop()\n })\n\n return {\n fields,\n steps,\n values,\n errors: readonly(errors),\n currentStep,\n stepIndex: readonly(stepIndex),\n isFirstStep,\n isLastStep,\n isSubmitting: readonly(isSubmitting),\n isSuccess: readonly(isSuccess),\n isPreview,\n error: readonly(error),\n fieldState,\n next,\n previous,\n validate,\n submit,\n reset,\n }\n}\n\nfunction normalizeFormValue(field: FormField, input: FormValues[string] | undefined): FormValues[string] {\n if (field.type === 'checkbox') return input === true\n\n if (field.type === 'number') {\n if (input === '' || input == null) return null\n const value = Schema.is(Schema.Finite)(input) || Schema.is(Schema.String)(input) ? Number(input) : Number.NaN\n\n if (Number.isFinite(value)) return value\n\n return Schema.is(Schema.String)(input) ? input : null\n }\n\n return Schema.is(Schema.String)(input) ? input : ''\n}\n\nfunction emptyFormValue(field: FormField): FormValues[string] {\n if (field.type === 'checkbox') return false\n\n if (field.type === 'number') return null\n\n return ''\n}\n\nasync function send(submission: FormSubmission, signal: AbortSignal): Promise<FormResult> {\n const response = await fetch(CMS_FORM_SUBMIT_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(submission),\n signal,\n })\n\n if (!response.ok) throw new Error('Submission failed.')\n\n return Result.getOrThrow(Schema.decodeUnknownResult(FormResult)(await response.json()))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useCmsForm.js","names":[],"sources":["../../../../../src/runtime/forms/useCmsForm.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ComputedRef, WritableComputedRef } from 'vue'\nimport type { FormDefinition, FormField, FormStep, FormSubmission, FormValues } from '@internal/protocol/Forms'\nimport { FormResult } from '@internal/protocol/Forms'\nimport { validateFormValues } from '@internal/document/Forms'\nimport { Result, Schema } from 'effect'\nimport {\n computed,\n getCurrentInstance,\n getCurrentScope,\n onScopeDispose,\n readonly,\n ref,\n shallowRef,\n toValue,\n useId,\n watch,\n} from 'vue'\nimport { CMS_FORM_SUBMIT_PATH } from '@internal/protocol/HttpPaths'\n\nexport interface UseCmsFormOptions {\n /** Replace the HTTP transport, retaining validation and submission state. */\n readonly submit?: (submission: FormSubmission, signal: AbortSignal) => Promise<FormResult>\n}\n\nexport interface CmsFormFieldController {\n readonly field: ComputedRef<FormField>\n readonly value: WritableComputedRef<FormValues[string]>\n readonly dirty: ComputedRef<boolean>\n readonly touched: ComputedRef<boolean>\n readonly valid: ComputedRef<boolean>\n readonly errors: ComputedRef<ReadonlyArray<string>>\n readonly controlAttrs: ComputedRef<{\n readonly id: string\n readonly name: string\n readonly required: boolean\n readonly 'aria-invalid': 'true' | undefined\n readonly 'aria-describedby': string | undefined\n }>\n readonly helpAttrs: { readonly id: string }\n readonly errorAttrs: { readonly id: string; readonly role: 'alert' }\n readonly touch: () => void\n}\n\nexport interface UseCmsFormReturn {\n readonly fields: ComputedRef<ReadonlyArray<FormField>>\n readonly steps: ComputedRef<ReadonlyArray<FormStep>>\n readonly values: Ref<Record<string, FormValues[string]>>\n readonly errors: Readonly<Ref<Readonly<Record<string, string>>>>\n readonly currentStep: ComputedRef<FormStep | undefined>\n readonly stepIndex: Readonly<Ref<number>>\n readonly isFirstStep: ComputedRef<boolean>\n readonly isLastStep: ComputedRef<boolean>\n readonly submitting: Readonly<Ref<boolean>>\n readonly isSuccess: Readonly<Ref<boolean>>\n readonly isPreview: ComputedRef<boolean>\n readonly submitError: Readonly<Ref<string | undefined>>\n readonly canSubmit: ComputedRef<boolean>\n readonly invalidFields: ComputedRef<ReadonlyArray<CmsFormFieldController>>\n readonly firstInvalidFieldId: ComputedRef<string | undefined>\n readonly field: (field: string | FormField) => CmsFormFieldController\n readonly next: () => boolean\n readonly previous: () => void\n readonly validate: () => boolean\n readonly submit: () => Promise<boolean>\n readonly reset: () => void\n}\n\n/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */\nexport function useCmsForm(input: MaybeRefOrGetter<FormDefinition>, options: UseCmsFormOptions = {}): UseCmsFormReturn {\n const fieldIdPrefix = getCurrentInstance() ? useId() : 'cms-form'\n const definition = computed(() => toValue(input))\n const steps = computed(() => definition.value.steps)\n const fields = computed(() => steps.value.flatMap((step) => step.fields))\n const values = ref<Record<string, FormValues[string]>>({})\n const errors = shallowRef<Record<string, string>>({})\n const stepIndex = ref(0)\n const currentStep = computed(() => steps.value[stepIndex.value])\n const isFirstStep = computed(() => stepIndex.value === 0)\n const isLastStep = computed(() => stepIndex.value === steps.value.length - 1)\n const submitting = ref(false)\n const isSuccess = ref(false)\n const isPreview = computed(() => definition.value.preview)\n const submitError = shallowRef<string>()\n const touched = ref(new Set<string>())\n const controllers = new Map<string, CmsFormFieldController>()\n let controller: AbortController | undefined\n let generation = 0\n let previousFields = new Map<string, string>()\n\n const stop = watch(\n definition,\n (next, before) => {\n generation++\n controller?.abort()\n submitting.value = false\n\n const sameForm =\n before?.documentId === next.documentId &&\n JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) &&\n before.name === next.name\n\n values.value = Object.fromEntries(\n next.steps\n .flatMap((step) => step.fields)\n .map((field) => [\n field.id,\n sameForm && previousFields.get(field.id) === field.type\n ? (values.value[field.id] ?? null)\n : field.type === 'checkbox'\n ? false\n : field.type === 'number'\n ? null\n : '',\n ]),\n )\n previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]))\n stepIndex.value = Math.max(\n 0,\n next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id),\n )\n errors.value = {}\n touched.value = new Set()\n submitError.value = undefined\n isSuccess.value = false\n },\n { immediate: true, deep: true, flush: 'sync' },\n )\n\n function validate(): boolean {\n touched.value = new Set(fields.value.map((field) => field.id))\n errors.value = validateFormValues(fields.value, values.value)\n\n return Object.keys(errors.value).length === 0\n }\n\n function field(input: string | FormField): CmsFormFieldController {\n const fieldId = Schema.is(Schema.String)(input) ? input : input.id\n const existing = controllers.get(fieldId)\n\n if (existing) return existing\n\n if (!fields.value.some((candidate) => candidate.id === fieldId))\n throw new Error(`Unknown CMS form field ${fieldId}.`)\n\n const current = computed(() => {\n const candidate = fields.value.find((field) => field.id === fieldId)\n\n if (!candidate) throw new Error(`CMS form field ${fieldId} no longer exists.`)\n\n return candidate\n })\n\n const controlId = `${fieldIdPrefix}-${encodeURIComponent(fieldId)}`\n const helpId = `${controlId}-help`\n const errorId = `${controlId}-error`\n\n const refreshError = () => {\n const issue = validateFormValues([current.value], values.value)[fieldId]\n const nextErrors = { ...errors.value }\n\n if (issue) nextErrors[fieldId] = issue\n else delete nextErrors[fieldId]\n errors.value = nextErrors\n }\n\n const controller: CmsFormFieldController = {\n field: current,\n value: computed({\n get: () => values.value[fieldId] ?? emptyFormValue(current.value),\n set: (value) => {\n values.value[fieldId] = normalizeFormValue(current.value, value)\n\n if (touched.value.has(fieldId) || errors.value[fieldId]) refreshError()\n },\n }),\n dirty: computed(() => values.value[fieldId] !== emptyFormValue(current.value)),\n touched: computed(() => touched.value.has(fieldId)),\n valid: computed(() => validateFormValues([current.value], values.value)[fieldId] === undefined),\n errors: computed(() => (errors.value[fieldId] ? [errors.value[fieldId]] : [])),\n controlAttrs: computed(() => {\n const fieldError = errors.value[fieldId]\n\n const describedBy = [current.value.help ? helpId : undefined, fieldError ? errorId : undefined]\n .filter((part) => part !== undefined)\n .join(' ')\n\n return {\n id: controlId,\n name: fieldId,\n required: current.value.required === true,\n 'aria-invalid': fieldError ? 'true' : undefined,\n 'aria-describedby': describedBy || undefined,\n }\n }),\n helpAttrs: { id: helpId },\n errorAttrs: { id: errorId, role: 'alert' },\n touch: () => {\n touched.value = new Set([...touched.value, fieldId])\n refreshError()\n },\n }\n\n controllers.set(fieldId, controller)\n\n return controller\n }\n\n function next(): boolean {\n if (submitting.value || isLastStep.value) return false\n const stepFields = currentStep.value?.fields ?? []\n touched.value = new Set([...touched.value, ...stepFields.map((field) => field.id)])\n const issues = validateFormValues(stepFields, values.value)\n errors.value = {\n ...Object.fromEntries(\n Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id)),\n ),\n ...issues,\n }\n\n if (Object.keys(issues).length) return false\n stepIndex.value++\n\n return true\n }\n\n function previous(): void {\n if (!submitting.value && !isFirstStep.value) stepIndex.value--\n }\n\n function reset(): void {\n generation++\n controller?.abort()\n submitting.value = false\n values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]))\n errors.value = {}\n touched.value = new Set()\n submitError.value = undefined\n isSuccess.value = false\n stepIndex.value = 0\n }\n\n async function submit(): Promise<boolean> {\n if (submitting.value || isSuccess.value) return false\n submitError.value = undefined\n\n if (!validate()) {\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n return false\n }\n\n if (isPreview.value) {\n isSuccess.value = true\n\n return true\n }\n\n const currentGeneration = ++generation\n controller = new AbortController()\n submitting.value = true\n\n try {\n const { documentId, nodePath, revision } = definition.value\n\n const result = await (options.submit ?? send)(\n { documentId, nodePath, revision, values: { ...values.value } },\n controller.signal,\n )\n\n if (generation !== currentGeneration) return false\n errors.value = { ...result.errors }\n isSuccess.value = result.status === 'accepted'\n\n if (result.status === 'invalid')\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n if (result.status !== 'accepted' && result.status !== 'invalid')\n submitError.value =\n result.status === 'stale'\n ? 'This form has changed. Reload the page before submitting.'\n : 'Submission failed. Please try again.'\n\n return isSuccess.value\n } catch {\n if (generation === currentGeneration) submitError.value = 'Submission failed. Please try again.'\n\n return false\n } finally {\n if (generation === currentGeneration) submitting.value = false\n }\n }\n\n if (getCurrentScope())\n onScopeDispose(() => {\n generation++\n controller?.abort()\n stop()\n })\n\n const invalidFields = computed(() => fields.value.map((entry) => field(entry)).filter((entry) => !entry.valid.value))\n const firstInvalidFieldId = computed(() => invalidFields.value[0]?.controlAttrs.value.id)\n const canSubmit = computed(() => !submitting.value && !isSuccess.value && invalidFields.value.length === 0)\n\n return {\n fields,\n steps,\n values,\n errors: readonly(errors),\n currentStep,\n stepIndex: readonly(stepIndex),\n isFirstStep,\n isLastStep,\n submitting: readonly(submitting),\n isSuccess: readonly(isSuccess),\n isPreview,\n submitError: readonly(submitError),\n canSubmit,\n invalidFields,\n firstInvalidFieldId,\n field,\n next,\n previous,\n validate,\n submit,\n reset,\n }\n}\n\nfunction normalizeFormValue(field: FormField, input: FormValues[string] | undefined): FormValues[string] {\n if (field.type === 'checkbox') return input === true\n\n if (field.type === 'number') {\n if (input === '' || input == null) return null\n const value = Schema.is(Schema.Finite)(input) || Schema.is(Schema.String)(input) ? Number(input) : Number.NaN\n\n if (Number.isFinite(value)) return value\n\n return Schema.is(Schema.String)(input) ? input : null\n }\n\n return Schema.is(Schema.String)(input) ? input : ''\n}\n\nfunction emptyFormValue(field: FormField): FormValues[string] {\n if (field.type === 'checkbox') return false\n\n if (field.type === 'number') return null\n\n return ''\n}\n\nasync function send(submission: FormSubmission, signal: AbortSignal): Promise<FormResult> {\n const response = await fetch(CMS_FORM_SUBMIT_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(submission),\n signal,\n })\n\n if (!response.ok) throw new Error('Submission failed.')\n\n return Result.getOrThrow(Schema.decodeUnknownResult(FormResult)(await response.json()))\n}\n"],"mappings":"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"}
@@ -1,11 +1,13 @@
1
- import { CmsMessageKey } from "../../I18n.js";
1
+ import { a as CmsMessageParameters, i as CmsMessageKey, r as CmsLocale } from "../../I18n-BXlVunfa.js";
2
+ import { ComputedRef } from "vue";
2
3
  //#region src/runtime/i18n/useCmsI18n.d.ts
4
+ export interface UseCmsI18nReturn {
5
+ readonly locale: ComputedRef<CmsLocale>;
6
+ readonly localePath: (path: string, code?: CmsLocale) => string;
7
+ readonly switchLocalePath: (code: CmsLocale, destination?: string) => string;
8
+ readonly t: <Key extends CmsMessageKey>(key: Key, ...arguments_: keyof CmsMessageParameters<Key> extends never ? [parameters?: undefined] : [parameters: CmsMessageParameters<Key>]) => string;
9
+ }
3
10
  /** URL-owned locale is reactive and isolated to the current Nuxt application/request. */
4
- export declare function useCmsI18n(): {
5
- locale: import("vue").ComputedRef<string>;
6
- localePath: (path: string, code?: string) => string;
7
- switchLocalePath: (code: string, destination?: string) => string;
8
- t: (key: CmsMessageKey, parameters?: Readonly<Record<string, string | number>>) => string;
9
- };
11
+ export declare function useCmsI18n(): UseCmsI18nReturn;
10
12
  //#endregion
11
13
  //# sourceMappingURL=useCmsI18n.d.ts.map
@@ -1,13 +1,14 @@
1
1
  import { localeFromPath, localePath, switchLocalePath, translate } from "./translator.js";
2
2
  import { computed } from "vue";
3
- import { useRoute } from "nuxt/app";
3
+ import { useRoute, useState } from "nuxt/app";
4
4
  import configuration from "#cms/i18n";
5
5
 
6
6
  //#region src/runtime/i18n/useCmsI18n.ts
7
7
  /** URL-owned locale is reactive and isolated to the current Nuxt application/request. */
8
8
  function useCmsI18n() {
9
9
  const route = useRoute();
10
- const locale = computed(() => localeFromPath(configuration, route.path));
10
+ const documentLocale = useState("cms-document-locale", () => void 0);
11
+ const locale = computed(() => documentLocale.value ?? localeFromPath(configuration, route.path));
11
12
  const warned = /* @__PURE__ */ new Set();
12
13
  function missing(key, code) {
13
14
  const id = `${code}:${key}`;
@@ -15,8 +16,8 @@ function useCmsI18n() {
15
16
  warned.add(id);
16
17
  console.warn(`[cms i18n] Missing message "${key}" for locale "${code}".`);
17
18
  }
18
- function t(key, parameters) {
19
- return translate(configuration, locale.value, key, parameters, missing);
19
+ function t(key, ...arguments_) {
20
+ return translate(configuration, locale.value, key, arguments_[0], missing);
20
21
  }
21
22
  function localePath$1(path, code = locale.value) {
22
23
  return localePath(configuration, path, code);
@@ -1 +1 @@
1
- {"version":3,"file":"useCmsI18n.js","names":["localePath","resolveLocalePath","switchLocalePath","resolveSwitchLocalePath"],"sources":["../../../../../src/runtime/i18n/useCmsI18n.ts"],"sourcesContent":["import configuration from '#cms/i18n'\nimport { useRoute } from 'nuxt/app'\nimport { computed } from 'vue'\nimport type { CmsMessageKey } from '../../I18n'\nimport {\n localeFromPath,\n localePath as resolveLocalePath,\n switchLocalePath as resolveSwitchLocalePath,\n translate,\n} from './translator'\n\n/** URL-owned locale is reactive and isolated to the current Nuxt application/request. */\nexport function useCmsI18n() {\n const route = useRoute()\n const locale = computed(() => localeFromPath(configuration, route.path))\n const warned = new Set<string>()\n\n function missing(key: string, code: string): void {\n const id = `${code}:${key}`\n\n if (!import.meta.dev || warned.has(id)) return\n warned.add(id)\n // Browser diagnostics should not add an Effect runtime to the website translation bundle.\n // oxlint-disable-next-line effecttsgo/global-console\n console.warn(`[cms i18n] Missing message \"${key}\" for locale \"${code}\".`)\n }\n\n function t(key: CmsMessageKey, parameters?: Readonly<Record<string, string | number>>): string {\n return translate(configuration, locale.value, key, parameters, missing)\n }\n\n function localePath(path: string, code = locale.value): string {\n return resolveLocalePath(configuration, path, code)\n }\n\n function switchLocalePath(code: string, destination?: string): string {\n return destination === undefined\n ? resolveSwitchLocalePath(configuration, route.fullPath, code)\n : resolveLocalePath(configuration, destination, code)\n }\n\n return { locale, localePath, switchLocalePath, t }\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,aAAa;CAC3B,MAAM,QAAQ,SAAS;CACvB,MAAM,SAAS,eAAe,eAAe,eAAe,MAAM,IAAI,CAAC;CACvE,MAAM,yBAAS,IAAI,IAAY;CAE/B,SAAS,QAAQ,KAAa,MAAoB;EAChD,MAAM,KAAK,GAAG,KAAK,GAAG;EAEtB,IAAI,CAAC,YAAY,OAAO,OAAO,IAAI,EAAE,GAAG;EACxC,OAAO,IAAI,EAAE;EAGb,QAAQ,KAAK,+BAA+B,IAAI,gBAAgB,KAAK,GAAG;CAC1E;CAEA,SAAS,EAAE,KAAoB,YAAgE;EAC7F,OAAO,UAAU,eAAe,OAAO,OAAO,KAAK,YAAY,OAAO;CACxE;CAEA,SAASA,aAAW,MAAc,OAAO,OAAO,OAAe;EAC7D,OAAOC,WAAkB,eAAe,MAAM,IAAI;CACpD;CAEA,SAASC,mBAAiB,MAAc,aAA8B;EACpE,OAAO,gBAAgB,SACnBC,iBAAwB,eAAe,MAAM,UAAU,IAAI,IAC3DF,WAAkB,eAAe,aAAa,IAAI;CACxD;CAEA,OAAO;EAAE;EAAQ;EAAY;EAAkB;CAAE;AACnD"}
1
+ {"version":3,"file":"useCmsI18n.js","names":["localePath","resolveLocalePath","switchLocalePath","resolveSwitchLocalePath"],"sources":["../../../../../src/runtime/i18n/useCmsI18n.ts"],"sourcesContent":["import configuration from '#cms/i18n'\nimport { useRoute, useState } from 'nuxt/app'\nimport { computed, type ComputedRef } from 'vue'\nimport type { CmsLocale, CmsMessageKey, CmsMessageParameters } from '../../I18n'\nimport {\n localeFromPath,\n localePath as resolveLocalePath,\n switchLocalePath as resolveSwitchLocalePath,\n translate,\n} from './translator'\n\nexport interface UseCmsI18nReturn {\n readonly locale: ComputedRef<CmsLocale>\n readonly localePath: (path: string, code?: CmsLocale) => string\n readonly switchLocalePath: (code: CmsLocale, destination?: string) => string\n readonly t: <Key extends CmsMessageKey>(\n key: Key,\n ...arguments_: keyof CmsMessageParameters<Key> extends never\n ? [parameters?: undefined]\n : [parameters: CmsMessageParameters<Key>]\n ) => string\n}\n\n/** URL-owned locale is reactive and isolated to the current Nuxt application/request. */\nexport function useCmsI18n(): UseCmsI18nReturn {\n const route = useRoute()\n const documentLocale = useState<string | undefined>('cms-document-locale', () => undefined)\n\n // SAFETY: compileCmsI18n generated CmsLocale from these exact runtime locale keys.\n const locale = computed<CmsLocale>(\n () => (documentLocale.value ?? localeFromPath(configuration, route.path)) as CmsLocale,\n )\n\n const warned = new Set<string>()\n\n function missing(key: string, code: string): void {\n const id = `${code}:${key}`\n\n if (!import.meta.dev || warned.has(id)) return\n warned.add(id)\n // Browser diagnostics should not add an Effect runtime to the website translation bundle.\n // oxlint-disable-next-line effecttsgo/global-console\n console.warn(`[cms i18n] Missing message \"${key}\" for locale \"${code}\".`)\n }\n\n function t<Key extends CmsMessageKey>(\n key: Key,\n ...arguments_: keyof CmsMessageParameters<Key> extends never\n ? [parameters?: undefined]\n : [parameters: CmsMessageParameters<Key>]\n ): string {\n return translate(configuration, locale.value, key, arguments_[0], missing)\n }\n\n function localePath(path: string, code: CmsLocale = locale.value): string {\n return resolveLocalePath(configuration, path, code)\n }\n\n function switchLocalePath(code: CmsLocale, destination?: string): string {\n return destination === undefined\n ? resolveSwitchLocalePath(configuration, route.fullPath, code)\n : resolveLocalePath(configuration, destination, code)\n }\n\n return { locale, localePath, switchLocalePath, t }\n}\n"],"mappings":";;;;;;;AAwBA,SAAgB,aAA+B;CAC7C,MAAM,QAAQ,SAAS;CACvB,MAAM,iBAAiB,SAA6B,6BAA6B,MAAS;CAG1F,MAAM,SAAS,eACN,eAAe,SAAS,eAAe,eAAe,MAAM,IAAI,CACzE;CAEA,MAAM,yBAAS,IAAI,IAAY;CAE/B,SAAS,QAAQ,KAAa,MAAoB;EAChD,MAAM,KAAK,GAAG,KAAK,GAAG;EAEtB,IAAI,CAAC,YAAY,OAAO,OAAO,IAAI,EAAE,GAAG;EACxC,OAAO,IAAI,EAAE;EAGb,QAAQ,KAAK,+BAA+B,IAAI,gBAAgB,KAAK,GAAG;CAC1E;CAEA,SAAS,EACP,KACA,GAAG,YAGK;EACR,OAAO,UAAU,eAAe,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO;CAC3E;CAEA,SAASA,aAAW,MAAc,OAAkB,OAAO,OAAe;EACxE,OAAOC,WAAkB,eAAe,MAAM,IAAI;CACpD;CAEA,SAASC,mBAAiB,MAAiB,aAA8B;EACvE,OAAO,gBAAgB,SACnBC,iBAAwB,eAAe,MAAM,UAAU,IAAI,IAC3DF,WAAkB,eAAe,aAAa,IAAI;CACxD;CAEA,OAAO;EAAE;EAAQ;EAAY;EAAkB;CAAE;AACnD"}
@@ -1,3 +1,3 @@
1
- import { n as toS3MediaObjectStoreOptions, t as installCms } from "../installation-CNfIriVm.js";
1
+ import { n as scopedDatabaseUrl, r as toS3MediaObjectStoreOptions, t as installCms } from "../installation-DsGst1BH.js";
2
2
 
3
- export { installCms, toS3MediaObjectStoreOptions };
3
+ export { installCms, scopedDatabaseUrl, toS3MediaObjectStoreOptions };
@@ -1,5 +1,5 @@
1
1
  import { resolveCmsInstallation } from "../internal/configuration.js";
2
- import { t as installCms } from "../installation-CNfIriVm.js";
2
+ import { t as installCms } from "../installation-DsGst1BH.js";
3
3
  import { Effect } from "effect";
4
4
  import { defineNitroPlugin, useNitroApp } from "nitropack/runtime";
5
5
 
@@ -1,3 +1,3 @@
1
- import { t as openSitePreviewConnection } from "../../connection-CBAy2qGy.js";
1
+ import { t as openSitePreviewConnection } from "../../connection-BPf4BQUZ.js";
2
2
 
3
3
  export { openSitePreviewConnection };
@@ -1,6 +1,6 @@
1
1
  import { a as EditorNodeId, l as RevisionNumber, r as DocumentId } from "../../scalars-B2lgGUnj.js";
2
- import { Et as RequestId } from "../../models-Bah5B3bT.js";
3
- import { r as PreviewIntentId } from "../../models-B4IoTmp7.js";
2
+ import { Et as RequestId } from "../../models-DgkGTFus.js";
3
+ import { r as PreviewIntentId } from "../../models-k2nXyD6q.js";
4
4
  import { mountPreviewOverlay } from "./overlay.js";
5
5
  import { clearPreviewTargets, decoratePreviewTargets, findPreviewNodeId, nearestPreviewElement, resolvePreviewTarget } from "./targets.js";
6
6
  import { Crypto, Effect, PlatformError, Schema } from "effect";
@@ -1,10 +1,10 @@
1
1
  import { o as PublicPath } from "../../scalars-B2lgGUnj.js";
2
- import { t as openSitePreviewConnection } from "../../connection-CBAy2qGy.js";
3
- import { n as readPreviewLocation, r as withPreviewLocation } from "../../location-BTqdfIzX.js";
2
+ import { t as openSitePreviewConnection } from "../../connection-BPf4BQUZ.js";
3
+ import { n as readPreviewLocation, r as withPreviewLocation } from "../../location-BgYhXEZp.js";
4
4
  import { formComponentsKey } from "../delivery/blocks.js";
5
5
  import { documentPreviewStoreKey } from "../delivery/preview.js";
6
6
  import { mountPreviewController } from "./controller.js";
7
- import { t as createStudioPreviewStore } from "../../store-b2CSXgMt.js";
7
+ import { t as createStudioPreviewStore } from "../../store-BYgSt7E3.js";
8
8
  import { Result, Schema } from "effect";
9
9
  import { inject, watch } from "vue";
10
10
  import { defineNuxtPlugin, navigateTo, onNuxtReady, useNuxtApp, useState } from "nuxt/app";
@@ -1,4 +1,4 @@
1
1
  import { documentPreviewStoreKey } from "../delivery/preview.js";
2
- import { t as createStudioPreviewStore } from "../../store-b2CSXgMt.js";
2
+ import { t as createStudioPreviewStore } from "../../store-BYgSt7E3.js";
3
3
 
4
4
  export { createStudioPreviewStore, documentPreviewStoreKey };
@@ -1,4 +1,4 @@
1
- import { q as SitemapEntry } from "../models-Bah5B3bT.js";
1
+ import { q as SitemapEntry } from "../models-DgkGTFus.js";
2
2
  import { i as CMS_DELIVERY_SITEMAP_PATH } from "../HttpPaths-c9nLZ9H2.js";
3
3
  import { useCmsInstallation } from "./plugin.js";
4
4
  import { toNuxtSitemapEntries } from "./sitemap-entries.js";
@@ -0,0 +1,7 @@
1
+ import { Schema } from "effect";
2
+ //#region ../protocol/src/internal/documents/scalars.d.ts
3
+ declare const DocumentId: Schema.brand<Schema.String, "DocumentId">;
4
+ type DocumentId = typeof DocumentId.Type;
5
+ //#endregion
6
+ export { DocumentId as t };
7
+ //# sourceMappingURL=scalars-CA6kyipS.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { o as PublicPath, r as DocumentId } from "./scalars-B2lgGUnj.js";
2
- import { f as mutableJson, p as mutableJsonObject } from "./Forms-Dj6NuW66.js";
3
- import { Ct as CollectionName, n as CmsMarkdownDocument } from "./models-Bah5B3bT.js";
2
+ import { Ct as CollectionName, n as CmsMarkdownDocument } from "./models-DgkGTFus.js";
3
+ import { f as mutableJson, p as mutableJsonObject } from "./Forms-02-p8qEw.js";
4
4
  import { n as editorMetadata } from "./metadata-BEZPWh-3.js";
5
5
  import { prepareFormDocument } from "./runtime/forms/document.js";
6
6
  import { CMS_PREVIEW_INLINE_HOST_ATTRIBUTE, CMS_PREVIEW_MARKER_TAG, CMS_PREVIEW_NODE_ATTRIBUTE, CMS_PREVIEW_TARGET_ATTRIBUTE, CMS_PREVIEW_WRAPPER_ATTRIBUTE } from "./runtime/preview/protocol.js";
@@ -223,4 +223,4 @@ function createPreviewDocument(body) {
223
223
 
224
224
  //#endregion
225
225
  export { createStudioPreviewStore as t };
226
- //# sourceMappingURL=store-b2CSXgMt.js.map
226
+ //# sourceMappingURL=store-BYgSt7E3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store-b2CSXgMt.js","names":["CmsMarkdownDocumentSchema"],"sources":["../../../../document/src/PreviewProjection.ts","../../../src/runtime/preview/store.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport { CmsMarkdownDocument as CmsMarkdownDocumentSchema } from '@internal/protocol/Documents'\nimport { Predicate, Result, Schema } from 'effect'\nimport { mutableJson, mutableJsonObject } from './internal/comark/document-adapter'\nimport { editorMetadata } from './internal/editor/metadata'\n\nexport interface PreviewProjectionMarkers {\n readonly inlineHostAttribute: string\n readonly markerTag: string\n readonly nodeAttribute: string\n readonly targetAttribute: string\n readonly wrapperAttribute: string\n}\n\nexport interface PreviewProjection {\n readonly body: CmsMarkdownDocument\n readonly fallbacks: Readonly<Record<string, string>>\n}\n\nexport class PreviewProjectionInvalid extends Schema.TaggedError<PreviewProjectionInvalid>()(\n 'PreviewProjection.Invalid',\n {\n message: Schema.NonEmptyString,\n cause: Schema.Defect(),\n },\n) {}\n\nconst NATIVE_BLOCK_TAGS = new Set([\n 'blockquote',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'img',\n 'li',\n 'math',\n 'ol',\n 'p',\n 'pre',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n])\n\nconst INLINE_TAGS = new Set(['a', 'br', 'code', 'del', 'em', 'img', 'strong', 'u'])\n\nexport function projectPreviewDocument(\n body: CmsMarkdownDocument,\n markers: PreviewProjectionMarkers,\n): Result.Result<PreviewProjection, PreviewProjectionInvalid> {\n return Result.try({\n try: () => projectPreviewDocumentUnsafe(body, markers),\n catch: (cause) =>\n new PreviewProjectionInvalid({\n cause,\n message: cause instanceof Error && cause.message ? cause.message : 'The preview projection is invalid.',\n }),\n })\n}\n\nfunction projectPreviewDocumentUnsafe(body: CmsMarkdownDocument, markers: PreviewProjectionMarkers): PreviewProjection {\n const fallbacks: Record<string, string> = {}\n let identifiedTargets = 0\n\n const cloneNodes = (nodes: ReadonlyArray<MarkdownNode>, componentId?: EditorNodeId): ReadonlyArray<Schema.Json> =>\n nodes.map((node) => {\n if (Predicate.isString(node) || node[0] === null) return mutableJson(node)\n const [tag, originalAttributes, ...originalChildren] = node\n const isSlot = tag === 'template'\n const isNative = NATIVE_BLOCK_TAGS.has(tag)\n const attributes = mutableJsonObject(originalAttributes)\n const metadata = editorMetadata(attributes)\n const id = metadata?.nodeId\n\n if (id) {\n identifiedTargets++\n\n if (componentId) fallbacks[id] = componentId\n\n if (!isSlot && !isNative) {\n attributes[markers.nodeAttribute] = id\n attributes[markers.targetAttribute] = 'component'\n }\n }\n\n const nextComponentId = !isNative && !isSlot && id ? id : componentId\n const children = [...cloneNodes(originalChildren, nextComponentId)]\n\n if (id && metadata?.implicitSlotId && !isNative && !isSlot && hasImplicitDefaultContent(originalChildren)) {\n const slotId = metadata.implicitSlotId\n fallbacks[slotId] = id\n const markerChildren = hasInlineImplicitDefaultContent(originalChildren) ? children.splice(0) : []\n\n const markerAttributes = {\n [markers.nodeAttribute]: slotId,\n [markers.targetAttribute]: 'slot',\n [markers.wrapperAttribute]: '',\n }\n\n if (markerChildren.length) markerAttributes[markers.inlineHostAttribute] = ''\n children.unshift([markers.markerTag, markerAttributes, ...markerChildren])\n }\n\n if (isSlot && id) {\n children.unshift([\n markers.markerTag,\n {\n [markers.nodeAttribute]: id,\n [markers.targetAttribute]: 'slot',\n [markers.wrapperAttribute]: '',\n },\n ])\n }\n\n const cloned: Schema.Json = [tag, attributes, ...children]\n\n if (id && isNative) return previewWrapper(id, 'native', cloned, markers)\n\n if (id && !isNative && !isSlot) return previewWrapper(id, 'component', cloned, markers)\n\n return cloned\n })\n\n const nodes = cloneNodes(body.nodes)\n\n if (body.nodes.length && !identifiedTargets)\n throw new Error('Studio preview requires an identified authoring document.')\n\n return {\n body: CmsMarkdownDocumentSchema.make({\n frontmatter: mutableJsonObject(body.frontmatter),\n meta: mutableJsonObject(body.meta),\n nodes,\n }),\n fallbacks,\n }\n}\n\nfunction previewWrapper(\n nodeId: EditorNodeId,\n kind: 'component' | 'native' | 'slot',\n child: Schema.Json,\n markers: PreviewProjectionMarkers,\n): Schema.Json {\n return [\n markers.markerTag,\n {\n [markers.nodeAttribute]: nodeId,\n [markers.targetAttribute]: kind,\n [markers.wrapperAttribute]: '',\n },\n child,\n ]\n}\n\nfunction hasImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n const hasExplicitDefault = nodes.some(\n (node) => Array.isArray(node) && node[0] === 'template' && node[1].name === 'default',\n )\n\n return (\n !hasExplicitDefault && nodes.some((node) => (Predicate.isString(node) ? Boolean(node) : node[0] !== 'template'))\n )\n}\n\nfunction hasInlineImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n return (\n nodes.length > 0 &&\n nodes.every(\n (node) => Predicate.isString(node) || (Array.isArray(node) && node[0] !== null && INLINE_TAGS.has(node[0])),\n )\n )\n}\n","import { prepareFormDocument } from '../forms/document'\nimport type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { RenderedCompiledDocument, RenderedDocumentManifest } from '@internal/protocol/Preview'\nimport { projectPreviewDocument } from '@internal/document/PreviewProjection'\nimport { CollectionName } from '@internal/protocol/Configuration'\nimport { DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport { Result } from 'effect'\nimport { createComarkContext } from 'comark'\nimport { shallowReactive } from 'vue'\nimport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\nimport type { DocumentPreviewStore, PreviewDocumentRole } from '../delivery/preview'\nimport { toPreviewRenderDocument } from './comark-document'\nimport {\n CMS_PREVIEW_INLINE_HOST_ATTRIBUTE,\n CMS_PREVIEW_MARKER_TAG,\n CMS_PREVIEW_NODE_ATTRIBUTE,\n CMS_PREVIEW_TARGET_ATTRIBUTE,\n CMS_PREVIEW_WRAPPER_ATTRIBUTE,\n} from './protocol'\n\nexport { documentPreviewStoreKey, type DocumentPreviewStore, type PreviewDocumentRole } from '../delivery/preview'\n\nexport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\n\nexport interface StudioPreviewStore extends DocumentPreviewStore {\n readonly manifest: () => RenderedDocumentManifest\n readonly patch: (document: PreviewCompiledDocument) => Promise<Readonly<Record<string, string>>>\n readonly routeChanged: () => void\n readonly subscribe: (listener: (manifest: RenderedDocumentManifest) => void) => () => void\n}\n\nexport function createStudioPreviewStore(\n route: () => RenderedDocumentManifest['route'],\n forms: () => ReadonlyArray<ComponentDefinition> = () => [],\n): StudioPreviewStore {\n const context = createComarkContext()\n const patches = shallowReactive(new Map<string, PreviewCompiledDocument>())\n\n const registrations = new Map<\n symbol,\n { readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }\n >()\n\n const listeners = new Set<(manifest: RenderedDocumentManifest) => void>()\n\n const manifest = (): RenderedDocumentManifest => ({\n documents: renderedDocuments(registrations.values(), patches),\n route: route(),\n })\n\n const notify = (): void => {\n const value = manifest()\n\n for (const listener of listeners) listener(value)\n }\n\n return {\n manifest,\n async patch(document) {\n const preview = createPreviewDocument(document.body)\n const patched = prepareFormDocument({ ...document, body: preview.body }, forms(), true)\n patches.set(document.id, patched)\n const renderBody = toPreviewRenderDocument(patched.body)\n context.get(document.id, renderBody).set(renderBody)\n notify()\n\n return preview.fallbacks\n },\n register(document, role) {\n const registration = Symbol(document.id)\n registrations.set(registration, { document, role })\n notify()\n\n return () => {\n registrations.delete(registration)\n notify()\n }\n },\n resolve(document) {\n return patches.get(document.id) ?? document\n },\n routeChanged: notify,\n subscribe(listener) {\n listeners.add(listener)\n listener(manifest())\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction renderedDocuments(\n registrations: Iterable<{ readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }>,\n patches: ReadonlyMap<string, PreviewCompiledDocument>,\n): ReadonlyArray<RenderedCompiledDocument> {\n const priority = { embedded: 1, primary: 4, related: 2, summary: 3 } satisfies Record<PreviewDocumentRole, number>\n const documents = new Map<string, RenderedCompiledDocument>()\n\n for (const registration of registrations) {\n const document = patches.get(registration.document.id) ?? registration.document\n const current = documents.get(document.id)\n\n if (current && priority[current.role] >= priority[registration.role]) continue\n documents.set(document.id, {\n collection: CollectionName.make(document.collection),\n documentId: DocumentId.make(document.id),\n path: PublicPath.make(document.path),\n role: registration.role,\n title: document.title,\n })\n }\n\n return [...documents.values()].sort(\n (left, right) => priority[right.role] - priority[left.role] || left.title.localeCompare(right.title),\n )\n}\n\nfunction createPreviewDocument(body: PreviewCompiledDocument['body']) {\n const projection = projectPreviewDocument(body, {\n inlineHostAttribute: CMS_PREVIEW_INLINE_HOST_ATTRIBUTE,\n markerTag: CMS_PREVIEW_MARKER_TAG,\n nodeAttribute: CMS_PREVIEW_NODE_ATTRIBUTE,\n targetAttribute: CMS_PREVIEW_TARGET_ATTRIBUTE,\n wrapperAttribute: CMS_PREVIEW_WRAPPER_ATTRIBUTE,\n })\n\n if (Result.isFailure(projection)) throw projection.failure\n\n return projection.success\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAa,2BAAb,cAA8C,OAAO,YAAsC,CAAC,CAC1F,6BACA;CACE,SAAS,OAAO;CAChB,OAAO,OAAO,OAAO;AACvB,CACF,CAAC,CAAC,CAAC;AAEH,MAAM,oCAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,8BAAc,IAAI,IAAI;CAAC;CAAK;CAAM;CAAQ;CAAO;CAAM;CAAO;CAAU;AAAG,CAAC;AAElF,SAAgB,uBACd,MACA,SAC4D;CAC5D,OAAO,OAAO,IAAI;EAChB,WAAW,6BAA6B,MAAM,OAAO;EACrD,QAAQ,UACN,IAAI,yBAAyB;GAC3B;GACA,SAAS,iBAAiB,SAAS,MAAM,UAAU,MAAM,UAAU;EACrE,CAAC;CACL,CAAC;AACH;AAEA,SAAS,6BAA6B,MAA2B,SAAsD;CACrH,MAAM,YAAoC,CAAC;CAC3C,IAAI,oBAAoB;CAExB,MAAM,cAAc,OAAoC,gBACtD,MAAM,KAAK,SAAS;EAClB,IAAI,UAAU,SAAS,IAAI,KAAK,KAAK,OAAO,MAAM,OAAO,YAAY,IAAI;EACzE,MAAM,CAAC,KAAK,oBAAoB,GAAG,oBAAoB;EACvD,MAAM,SAAS,QAAQ;EACvB,MAAM,WAAW,kBAAkB,IAAI,GAAG;EAC1C,MAAM,aAAa,kBAAkB,kBAAkB;EACvD,MAAM,WAAW,eAAe,UAAU;EAC1C,MAAM,KAAK,UAAU;EAErB,IAAI,IAAI;GACN;GAEA,IAAI,aAAa,UAAU,MAAM;GAEjC,IAAI,CAAC,UAAU,CAAC,UAAU;IACxB,WAAW,QAAQ,iBAAiB;IACpC,WAAW,QAAQ,mBAAmB;GACxC;EACF;EAGA,MAAM,WAAW,CAAC,GAAG,WAAW,kBADR,CAAC,YAAY,CAAC,UAAU,KAAK,KAAK,WACO,CAAC;EAElE,IAAI,MAAM,UAAU,kBAAkB,CAAC,YAAY,CAAC,UAAU,0BAA0B,gBAAgB,GAAG;GACzG,MAAM,SAAS,SAAS;GACxB,UAAU,UAAU;GACpB,MAAM,iBAAiB,gCAAgC,gBAAgB,IAAI,SAAS,OAAO,CAAC,IAAI,CAAC;GAEjG,MAAM,mBAAmB;KACtB,QAAQ,gBAAgB;KACxB,QAAQ,kBAAkB;KAC1B,QAAQ,mBAAmB;GAC9B;GAEA,IAAI,eAAe,QAAQ,iBAAiB,QAAQ,uBAAuB;GAC3E,SAAS,QAAQ;IAAC,QAAQ;IAAW;IAAkB,GAAG;GAAc,CAAC;EAC3E;EAEA,IAAI,UAAU,IACZ,SAAS,QAAQ,CACf,QAAQ,WACR;IACG,QAAQ,gBAAgB;IACxB,QAAQ,kBAAkB;IAC1B,QAAQ,mBAAmB;EAC9B,CACF,CAAC;EAGH,MAAM,SAAsB;GAAC;GAAK;GAAY,GAAG;EAAQ;EAEzD,IAAI,MAAM,UAAU,OAAO,eAAe,IAAI,UAAU,QAAQ,OAAO;EAEvE,IAAI,MAAM,CAAC,YAAY,CAAC,QAAQ,OAAO,eAAe,IAAI,aAAa,QAAQ,OAAO;EAEtF,OAAO;CACT,CAAC;CAEH,MAAM,QAAQ,WAAW,KAAK,KAAK;CAEnC,IAAI,KAAK,MAAM,UAAU,CAAC,mBACxB,MAAM,IAAI,MAAM,2DAA2D;CAE7E,OAAO;EACL,MAAMA,oBAA0B,KAAK;GACnC,aAAa,kBAAkB,KAAK,WAAW;GAC/C,MAAM,kBAAkB,KAAK,IAAI;GACjC;EACF,CAAC;EACD;CACF;AACF;AAEA,SAAS,eACP,QACA,MACA,OACA,SACa;CACb,OAAO;EACL,QAAQ;EACR;IACG,QAAQ,gBAAgB;IACxB,QAAQ,kBAAkB;IAC1B,QAAQ,mBAAmB;EAC9B;EACA;CACF;AACF;AAEA,SAAS,0BAA0B,OAA6C;CAK9E,OACE,CALyB,MAAM,MAC9B,SAAS,MAAM,QAAQ,IAAI,KAAK,KAAK,OAAO,cAAc,KAAK,EAAE,CAAC,SAAS,SAI1D,KAAK,MAAM,MAAM,SAAU,UAAU,SAAS,IAAI,IAAI,QAAQ,IAAI,IAAI,KAAK,OAAO,UAAW;AAEnH;AAEA,SAAS,gCAAgC,OAA6C;CACpF,OACE,MAAM,SAAS,KACf,MAAM,OACH,SAAS,UAAU,SAAS,IAAI,KAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAE,CAC3G;AAEJ;;;;ACrJA,SAAgB,yBACd,OACA,cAAwD,CAAC,GACrC;CACpB,MAAM,UAAU,oBAAoB;CACpC,MAAM,UAAU,gCAAgB,IAAI,IAAqC,CAAC;CAE1E,MAAM,gCAAgB,IAAI,IAGxB;CAEF,MAAM,4BAAY,IAAI,IAAkD;CAExE,MAAM,kBAA4C;EAChD,WAAW,kBAAkB,cAAc,OAAO,GAAG,OAAO;EAC5D,OAAO,MAAM;CACf;CAEA,MAAM,eAAqB;EACzB,MAAM,QAAQ,SAAS;EAEvB,KAAK,MAAM,YAAY,WAAW,SAAS,KAAK;CAClD;CAEA,OAAO;EACL;EACA,MAAM,MAAM,UAAU;GACpB,MAAM,UAAU,sBAAsB,SAAS,IAAI;GACnD,MAAM,UAAU,oBAAoB;IAAE,GAAG;IAAU,MAAM,QAAQ;GAAK,GAAG,MAAM,GAAG,IAAI;GACtF,QAAQ,IAAI,SAAS,IAAI,OAAO;GAChC,MAAM,aAAa,wBAAwB,QAAQ,IAAI;GACvD,QAAQ,IAAI,SAAS,IAAI,UAAU,CAAC,CAAC,IAAI,UAAU;GACnD,OAAO;GAEP,OAAO,QAAQ;EACjB;EACA,SAAS,UAAU,MAAM;GACvB,MAAM,eAAe,OAAO,SAAS,EAAE;GACvC,cAAc,IAAI,cAAc;IAAE;IAAU;GAAK,CAAC;GAClD,OAAO;GAEP,aAAa;IACX,cAAc,OAAO,YAAY;IACjC,OAAO;GACT;EACF;EACA,QAAQ,UAAU;GAChB,OAAO,QAAQ,IAAI,SAAS,EAAE,KAAK;EACrC;EACA,cAAc;EACd,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,SAAS,SAAS,CAAC;GAEnB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;AAEA,SAAS,kBACP,eACA,SACyC;CACzC,MAAM,WAAW;EAAE,UAAU;EAAG,SAAS;EAAG,SAAS;EAAG,SAAS;CAAE;CACnE,MAAM,4BAAY,IAAI,IAAsC;CAE5D,KAAK,MAAM,gBAAgB,eAAe;EACxC,MAAM,WAAW,QAAQ,IAAI,aAAa,SAAS,EAAE,KAAK,aAAa;EACvE,MAAM,UAAU,UAAU,IAAI,SAAS,EAAE;EAEzC,IAAI,WAAW,SAAS,QAAQ,SAAS,SAAS,aAAa,OAAO;EACtE,UAAU,IAAI,SAAS,IAAI;GACzB,YAAY,eAAe,KAAK,SAAS,UAAU;GACnD,YAAY,WAAW,KAAK,SAAS,EAAE;GACvC,MAAM,WAAW,KAAK,SAAS,IAAI;GACnC,MAAM,aAAa;GACnB,OAAO,SAAS;EAClB,CAAC;CACH;CAEA,OAAO,CAAC,GAAG,UAAU,OAAO,CAAC,CAAC,CAAC,MAC5B,MAAM,UAAU,SAAS,MAAM,QAAQ,SAAS,KAAK,SAAS,KAAK,MAAM,cAAc,MAAM,KAAK,CACrG;AACF;AAEA,SAAS,sBAAsB,MAAuC;CACpE,MAAM,aAAa,uBAAuB,MAAM;EAC9C,qBAAqB;EACrB,WAAW;EACX,eAAe;EACf,iBAAiB;EACjB,kBAAkB;CACpB,CAAC;CAED,IAAI,OAAO,UAAU,UAAU,GAAG,MAAM,WAAW;CAEnD,OAAO,WAAW;AACpB"}
1
+ {"version":3,"file":"store-BYgSt7E3.js","names":["CmsMarkdownDocumentSchema"],"sources":["../../../../document/src/PreviewProjection.ts","../../../src/runtime/preview/store.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport { CmsMarkdownDocument as CmsMarkdownDocumentSchema } from '@internal/protocol/Documents'\nimport { Predicate, Result, Schema } from 'effect'\nimport { mutableJson, mutableJsonObject } from './internal/comark/document-adapter'\nimport { editorMetadata } from './internal/editor/metadata'\n\nexport interface PreviewProjectionMarkers {\n readonly inlineHostAttribute: string\n readonly markerTag: string\n readonly nodeAttribute: string\n readonly targetAttribute: string\n readonly wrapperAttribute: string\n}\n\nexport interface PreviewProjection {\n readonly body: CmsMarkdownDocument\n readonly fallbacks: Readonly<Record<string, string>>\n}\n\nexport class PreviewProjectionInvalid extends Schema.TaggedError<PreviewProjectionInvalid>()(\n 'PreviewProjection.Invalid',\n {\n message: Schema.NonEmptyString,\n cause: Schema.Defect(),\n },\n) {}\n\nconst NATIVE_BLOCK_TAGS = new Set([\n 'blockquote',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'img',\n 'li',\n 'math',\n 'ol',\n 'p',\n 'pre',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n])\n\nconst INLINE_TAGS = new Set(['a', 'br', 'code', 'del', 'em', 'img', 'strong', 'u'])\n\nexport function projectPreviewDocument(\n body: CmsMarkdownDocument,\n markers: PreviewProjectionMarkers,\n): Result.Result<PreviewProjection, PreviewProjectionInvalid> {\n return Result.try({\n try: () => projectPreviewDocumentUnsafe(body, markers),\n catch: (cause) =>\n new PreviewProjectionInvalid({\n cause,\n message: cause instanceof Error && cause.message ? cause.message : 'The preview projection is invalid.',\n }),\n })\n}\n\nfunction projectPreviewDocumentUnsafe(body: CmsMarkdownDocument, markers: PreviewProjectionMarkers): PreviewProjection {\n const fallbacks: Record<string, string> = {}\n let identifiedTargets = 0\n\n const cloneNodes = (nodes: ReadonlyArray<MarkdownNode>, componentId?: EditorNodeId): ReadonlyArray<Schema.Json> =>\n nodes.map((node) => {\n if (Predicate.isString(node) || node[0] === null) return mutableJson(node)\n const [tag, originalAttributes, ...originalChildren] = node\n const isSlot = tag === 'template'\n const isNative = NATIVE_BLOCK_TAGS.has(tag)\n const attributes = mutableJsonObject(originalAttributes)\n const metadata = editorMetadata(attributes)\n const id = metadata?.nodeId\n\n if (id) {\n identifiedTargets++\n\n if (componentId) fallbacks[id] = componentId\n\n if (!isSlot && !isNative) {\n attributes[markers.nodeAttribute] = id\n attributes[markers.targetAttribute] = 'component'\n }\n }\n\n const nextComponentId = !isNative && !isSlot && id ? id : componentId\n const children = [...cloneNodes(originalChildren, nextComponentId)]\n\n if (id && metadata?.implicitSlotId && !isNative && !isSlot && hasImplicitDefaultContent(originalChildren)) {\n const slotId = metadata.implicitSlotId\n fallbacks[slotId] = id\n const markerChildren = hasInlineImplicitDefaultContent(originalChildren) ? children.splice(0) : []\n\n const markerAttributes = {\n [markers.nodeAttribute]: slotId,\n [markers.targetAttribute]: 'slot',\n [markers.wrapperAttribute]: '',\n }\n\n if (markerChildren.length) markerAttributes[markers.inlineHostAttribute] = ''\n children.unshift([markers.markerTag, markerAttributes, ...markerChildren])\n }\n\n if (isSlot && id) {\n children.unshift([\n markers.markerTag,\n {\n [markers.nodeAttribute]: id,\n [markers.targetAttribute]: 'slot',\n [markers.wrapperAttribute]: '',\n },\n ])\n }\n\n const cloned: Schema.Json = [tag, attributes, ...children]\n\n if (id && isNative) return previewWrapper(id, 'native', cloned, markers)\n\n if (id && !isNative && !isSlot) return previewWrapper(id, 'component', cloned, markers)\n\n return cloned\n })\n\n const nodes = cloneNodes(body.nodes)\n\n if (body.nodes.length && !identifiedTargets)\n throw new Error('Studio preview requires an identified authoring document.')\n\n return {\n body: CmsMarkdownDocumentSchema.make({\n frontmatter: mutableJsonObject(body.frontmatter),\n meta: mutableJsonObject(body.meta),\n nodes,\n }),\n fallbacks,\n }\n}\n\nfunction previewWrapper(\n nodeId: EditorNodeId,\n kind: 'component' | 'native' | 'slot',\n child: Schema.Json,\n markers: PreviewProjectionMarkers,\n): Schema.Json {\n return [\n markers.markerTag,\n {\n [markers.nodeAttribute]: nodeId,\n [markers.targetAttribute]: kind,\n [markers.wrapperAttribute]: '',\n },\n child,\n ]\n}\n\nfunction hasImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n const hasExplicitDefault = nodes.some(\n (node) => Array.isArray(node) && node[0] === 'template' && node[1].name === 'default',\n )\n\n return (\n !hasExplicitDefault && nodes.some((node) => (Predicate.isString(node) ? Boolean(node) : node[0] !== 'template'))\n )\n}\n\nfunction hasInlineImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n return (\n nodes.length > 0 &&\n nodes.every(\n (node) => Predicate.isString(node) || (Array.isArray(node) && node[0] !== null && INLINE_TAGS.has(node[0])),\n )\n )\n}\n","import { prepareFormDocument } from '../forms/document'\nimport type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { RenderedCompiledDocument, RenderedDocumentManifest } from '@internal/protocol/Preview'\nimport { projectPreviewDocument } from '@internal/document/PreviewProjection'\nimport { CollectionName } from '@internal/protocol/Configuration'\nimport { DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport { Result } from 'effect'\nimport { createComarkContext } from 'comark'\nimport { shallowReactive } from 'vue'\nimport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\nimport type { DocumentPreviewStore, PreviewDocumentRole } from '../delivery/preview'\nimport { toPreviewRenderDocument } from './comark-document'\nimport {\n CMS_PREVIEW_INLINE_HOST_ATTRIBUTE,\n CMS_PREVIEW_MARKER_TAG,\n CMS_PREVIEW_NODE_ATTRIBUTE,\n CMS_PREVIEW_TARGET_ATTRIBUTE,\n CMS_PREVIEW_WRAPPER_ATTRIBUTE,\n} from './protocol'\n\nexport { documentPreviewStoreKey, type DocumentPreviewStore, type PreviewDocumentRole } from '../delivery/preview'\n\nexport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\n\nexport interface StudioPreviewStore extends DocumentPreviewStore {\n readonly manifest: () => RenderedDocumentManifest\n readonly patch: (document: PreviewCompiledDocument) => Promise<Readonly<Record<string, string>>>\n readonly routeChanged: () => void\n readonly subscribe: (listener: (manifest: RenderedDocumentManifest) => void) => () => void\n}\n\nexport function createStudioPreviewStore(\n route: () => RenderedDocumentManifest['route'],\n forms: () => ReadonlyArray<ComponentDefinition> = () => [],\n): StudioPreviewStore {\n const context = createComarkContext()\n const patches = shallowReactive(new Map<string, PreviewCompiledDocument>())\n\n const registrations = new Map<\n symbol,\n { readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }\n >()\n\n const listeners = new Set<(manifest: RenderedDocumentManifest) => void>()\n\n const manifest = (): RenderedDocumentManifest => ({\n documents: renderedDocuments(registrations.values(), patches),\n route: route(),\n })\n\n const notify = (): void => {\n const value = manifest()\n\n for (const listener of listeners) listener(value)\n }\n\n return {\n manifest,\n async patch(document) {\n const preview = createPreviewDocument(document.body)\n const patched = prepareFormDocument({ ...document, body: preview.body }, forms(), true)\n patches.set(document.id, patched)\n const renderBody = toPreviewRenderDocument(patched.body)\n context.get(document.id, renderBody).set(renderBody)\n notify()\n\n return preview.fallbacks\n },\n register(document, role) {\n const registration = Symbol(document.id)\n registrations.set(registration, { document, role })\n notify()\n\n return () => {\n registrations.delete(registration)\n notify()\n }\n },\n resolve(document) {\n return patches.get(document.id) ?? document\n },\n routeChanged: notify,\n subscribe(listener) {\n listeners.add(listener)\n listener(manifest())\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction renderedDocuments(\n registrations: Iterable<{ readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }>,\n patches: ReadonlyMap<string, PreviewCompiledDocument>,\n): ReadonlyArray<RenderedCompiledDocument> {\n const priority = { embedded: 1, primary: 4, related: 2, summary: 3 } satisfies Record<PreviewDocumentRole, number>\n const documents = new Map<string, RenderedCompiledDocument>()\n\n for (const registration of registrations) {\n const document = patches.get(registration.document.id) ?? registration.document\n const current = documents.get(document.id)\n\n if (current && priority[current.role] >= priority[registration.role]) continue\n documents.set(document.id, {\n collection: CollectionName.make(document.collection),\n documentId: DocumentId.make(document.id),\n path: PublicPath.make(document.path),\n role: registration.role,\n title: document.title,\n })\n }\n\n return [...documents.values()].sort(\n (left, right) => priority[right.role] - priority[left.role] || left.title.localeCompare(right.title),\n )\n}\n\nfunction createPreviewDocument(body: PreviewCompiledDocument['body']) {\n const projection = projectPreviewDocument(body, {\n inlineHostAttribute: CMS_PREVIEW_INLINE_HOST_ATTRIBUTE,\n markerTag: CMS_PREVIEW_MARKER_TAG,\n nodeAttribute: CMS_PREVIEW_NODE_ATTRIBUTE,\n targetAttribute: CMS_PREVIEW_TARGET_ATTRIBUTE,\n wrapperAttribute: CMS_PREVIEW_WRAPPER_ATTRIBUTE,\n })\n\n if (Result.isFailure(projection)) throw projection.failure\n\n return projection.success\n}\n"],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { n as ResolvedSeo, t as DocumentSeo } from "./Seo-402YumpT.js";
2
+ import { DateTime } from "effect";
3
+ //#region src/runtime/delivery/types.d.ts
4
+ type DeliveryJson = null | boolean | number | string | ReadonlyArray<DeliveryJson> | DeliveryJsonObject;
5
+ interface DeliveryJsonObject {
6
+ readonly [key: string]: DeliveryJson;
7
+ }
8
+ type DeliveryMarkdownNode = string | readonly [null, DeliveryJsonObject, string] | readonly [string, DeliveryJsonObject, ...DeliveryMarkdownNode[]];
9
+ interface DeliveryMarkdownDocument {
10
+ readonly frontmatter: DeliveryJsonObject;
11
+ readonly meta: DeliveryJsonObject;
12
+ readonly nodes: ReadonlyArray<DeliveryMarkdownNode>;
13
+ }
14
+ interface DeliveryDocument {
15
+ readonly analysis: {
16
+ readonly components: ReadonlyArray<string>;
17
+ readonly headings: ReadonlyArray<{
18
+ readonly depth: number;
19
+ readonly id: string;
20
+ readonly text: string;
21
+ }>;
22
+ readonly searchText: string;
23
+ readonly summary: string;
24
+ };
25
+ readonly body: DeliveryMarkdownDocument;
26
+ readonly alternatives?: ReadonlyArray<{
27
+ readonly locale: string;
28
+ readonly path: string;
29
+ }>;
30
+ readonly collection: string;
31
+ readonly data: DeliveryJsonObject;
32
+ readonly description?: string;
33
+ readonly draft: boolean;
34
+ readonly engineFingerprint: string;
35
+ readonly id: string;
36
+ readonly issues: ReadonlyArray<{
37
+ readonly code: string;
38
+ readonly collection?: string;
39
+ readonly field?: string;
40
+ readonly key?: string;
41
+ readonly locale?: string;
42
+ readonly message: string;
43
+ readonly severity: 'error' | 'warning';
44
+ readonly sourcePath?: string;
45
+ }>;
46
+ readonly key: string;
47
+ readonly locale?: string;
48
+ readonly path: string;
49
+ readonly resolvedSeo?: ResolvedSeo;
50
+ readonly seo?: DocumentSeo;
51
+ readonly source: {
52
+ readonly mappings: ReadonlyArray<{
53
+ readonly nodePath: ReadonlyArray<number>;
54
+ readonly range: {
55
+ readonly end: {
56
+ readonly column: number;
57
+ readonly line: number;
58
+ readonly offset: number;
59
+ };
60
+ readonly start: {
61
+ readonly column: number;
62
+ readonly line: number;
63
+ readonly offset: number;
64
+ };
65
+ };
66
+ }>;
67
+ readonly path: string;
68
+ readonly publishedAt?: DateTime.Utc;
69
+ };
70
+ readonly title: string;
71
+ }
72
+ interface DeliveryDocumentPage {
73
+ readonly items: ReadonlyArray<DeliveryDocument>;
74
+ readonly total: number;
75
+ }
76
+ interface DeliveryDocumentQuerySort {
77
+ readonly direction?: 'asc' | 'desc';
78
+ readonly field: string;
79
+ }
80
+ interface DeliveryDocumentQuery {
81
+ readonly collection?: string;
82
+ readonly locale?: string;
83
+ readonly limit: number;
84
+ readonly offset?: number;
85
+ readonly sort?: DeliveryDocumentQuerySort | ReadonlyArray<DeliveryDocumentQuerySort>;
86
+ readonly where?: Readonly<Record<string, boolean | number | string | null | ReadonlyArray<boolean | number | string | null>>>;
87
+ }
88
+ //#endregion
89
+ export { DeliveryJson as a, DeliveryMarkdownNode as c, DeliveryDocumentQuerySort as i, DeliveryDocumentPage as n, DeliveryJsonObject as o, DeliveryDocumentQuery as r, DeliveryMarkdownDocument as s, DeliveryDocument as t };
90
+ //# sourceMappingURL=types-DutFRtaG.d.ts.map