@phtngyn/cms 0.1.0-beta.2 → 0.1.0-beta.3
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 +52 -35
- package/bin/cms.mjs +2 -0
- package/package.json +5 -5
- package/src/{Configuration-CA_jvQKG.js → Configuration-CDMYfTre.js} +3 -3
- package/src/{Configuration-CA_jvQKG.js.map → Configuration-CDMYfTre.js.map} +1 -1
- package/src/Configuration.d.ts +60 -2
- package/src/Configuration.js.map +1 -1
- package/src/ContentTransfer-C3Av9sWz.js +53 -0
- package/src/ContentTransfer-C3Av9sWz.js.map +1 -0
- package/src/{DocumentEngine-CgiBQU4g.js → DocumentEngine-J7g-emdf.js} +4 -4
- package/src/{DocumentEngine-CgiBQU4g.js.map → DocumentEngine-J7g-emdf.js.map} +1 -1
- package/src/DocumentModel.d.ts +33 -2
- package/src/{Forms-DxbkU3_5.js → Forms-Dj6NuW66.js} +2 -2
- package/src/{Forms-DxbkU3_5.js.map → Forms-Dj6NuW66.js.map} +1 -1
- package/src/Forms.d.ts +17 -1
- package/src/Forms.js.map +1 -1
- package/src/I18n.d.ts +20 -2
- package/src/Module.js +2 -3
- package/src/Module.js.map +1 -1
- package/src/{S3MediaObjects-JKMAWyVB.js → S3MediaObjects-CpPSzJto.js} +219 -106
- package/src/S3MediaObjects-CpPSzJto.js.map +1 -0
- package/src/cli/content.js +258 -0
- package/src/cli/content.js.map +1 -0
- package/src/cli.js +71 -0
- package/src/cli.js.map +1 -0
- package/src/{connection-B-iz0Y9Y.js → connection-CBAy2qGy.js} +2 -2
- package/src/{connection-B-iz0Y9Y.js.map → connection-CBAy2qGy.js.map} +1 -1
- package/src/{installation-DgF2M1gL.js → installation-CNfIriVm.js} +21 -23
- package/src/installation-CNfIriVm.js.map +1 -0
- package/src/internal/authoring-catalog.js +2 -2
- package/src/internal/authoring-metadata.js +1 -1
- package/src/internal/configuration.js +6 -10
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/document-model.js +7 -4
- package/src/internal/document-model.js.map +1 -1
- package/src/{location-CFKTeK1K.js → location-BTqdfIzX.js} +2 -2
- package/src/{location-CFKTeK1K.js.map → location-BTqdfIzX.js.map} +1 -1
- package/src/{models-BWm1pTAf.js → models-B4IoTmp7.js} +2 -2
- package/src/{models-BWm1pTAf.js.map → models-B4IoTmp7.js.map} +1 -1
- package/src/{models-DwYioyNV.js → models-Bah5B3bT.js} +4 -21
- package/src/models-Bah5B3bT.js.map +1 -0
- package/src/runtime/delivery/context.js +1 -1
- package/src/runtime/delivery/plugin.js +9 -3
- package/src/runtime/delivery/plugin.js.map +1 -1
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +3 -0
- package/src/runtime/delivery/useCmsDocumentSeo.js +3 -1
- package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
- package/src/runtime/forms/document.js +1 -1
- package/src/runtime/forms/useCmsForm.js +43 -2
- package/src/runtime/forms/useCmsForm.js.map +1 -1
- package/src/runtime/i18n/translator.js +31 -2
- package/src/runtime/i18n/translator.js.map +1 -1
- package/src/runtime/i18n/useCmsI18n.d.ts +3 -1
- package/src/runtime/i18n/useCmsI18n.js +9 -1
- package/src/runtime/i18n/useCmsI18n.js.map +1 -1
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +3 -3
- package/src/runtime/plugin.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +2 -2
- package/src/runtime/preview/plugin.client.js +3 -3
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +1 -1
- package/src/{store-DjJs3I7k.js → store-b2CSXgMt.js} +3 -3
- package/src/{store-DjJs3I7k.js.map → store-b2CSXgMt.js.map} +1 -1
- package/studio/{CreateDocumentDialog-CTeIFlPb.js → CreateDocumentDialog-GGey1uBc.js} +1 -1
- package/studio/{documentPlanning-Bfv-d7OU.js → documentPlanning-DRErYmBU.js} +1490 -1450
- package/studio/host.js +2 -2
- package/src/Configuration-Br7tE9Qt.d.ts +0 -68
- package/src/DocumentModel-BB9igGC7.d.ts +0 -34
- package/src/I18n-DZK4CkJF.d.ts +0 -21
- package/src/S3MediaObjects-JKMAWyVB.js.map +0 -1
- package/src/Seed.d.ts +0 -6
- package/src/Seed.js +0 -34
- package/src/Seed.js.map +0 -1
- package/src/installation-DgF2M1gL.js.map +0 -1
- package/src/models-DwYioyNV.js.map +0 -1
|
@@ -8,7 +8,8 @@ function installCmsDocumentSeoAdapters(adapters) {
|
|
|
8
8
|
}
|
|
9
9
|
function useCmsDocumentSeo(document) {
|
|
10
10
|
const adapters = installedCmsDocumentSeoAdapters();
|
|
11
|
-
const
|
|
11
|
+
const current = computed(() => toValue(document));
|
|
12
|
+
const seo = computed(() => resolvedSeo(current.value));
|
|
12
13
|
adapters.seoMeta({
|
|
13
14
|
title: () => seo.value?.title,
|
|
14
15
|
description: () => seo.value?.description,
|
|
@@ -19,6 +20,7 @@ function useCmsDocumentSeo(document) {
|
|
|
19
20
|
robots: () => seo.value ? `${seo.value.index ? "index" : "noindex"}, ${seo.value.follow ? "follow" : "nofollow"}` : void 0
|
|
20
21
|
});
|
|
21
22
|
adapters.head(() => ({
|
|
23
|
+
...current.value?.locale ? { htmlAttrs: { lang: current.value.locale } } : void 0,
|
|
22
24
|
link: seo.value?.canonicalUrl ? [{
|
|
23
25
|
href: seo.value.canonicalUrl,
|
|
24
26
|
rel: "canonical"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCmsDocumentSeo.js","names":[],"sources":["../../../../../src/runtime/delivery/useCmsDocumentSeo.ts"],"sourcesContent":["import type { ResolvedSeo, SiteIdentity } from '@internal/protocol/Seo'\nimport type { ComputedRef, MaybeRefOrGetter } from 'vue'\nimport type { DeliveryDocument } from './types'\nimport { computed, toValue } from 'vue'\n\ntype ReactiveMetadataValue = () => string | undefined\n\nexport interface CmsSeoMetadata {\n readonly title: ReactiveMetadataValue\n readonly description: ReactiveMetadataValue\n readonly ogTitle: ReactiveMetadataValue\n readonly ogDescription: ReactiveMetadataValue\n readonly ogImage: ReactiveMetadataValue\n readonly ogImageAlt: ReactiveMetadataValue\n readonly robots: ReactiveMetadataValue\n}\n\ninterface CmsIdentitySchemaNode {\n readonly '@type': SiteIdentity['type']\n readonly name: string\n readonly url?: string\n readonly image?: string\n readonly logo?: string\n readonly telephone?: string\n readonly address?: NonNullable<Extract<SiteIdentity, { readonly type: 'LocalBusiness' }>['address']>\n}\n\ninterface CmsPageSchemaNode {\n readonly '@type': 'Article' | 'WebPage'\n readonly name: string\n readonly description?: string\n readonly image?: string\n readonly url?: string\n readonly headline?: string\n readonly datePublished?: string\n readonly dateModified?: string\n}\n\nexport type CmsSeoSchemaNode = CmsIdentitySchemaNode | CmsPageSchemaNode\n\ntype EffectiveSeo = Omit<ResolvedSeo, 'canonicalUrl'> & {\n readonly canonicalUrl?: ResolvedSeo['canonicalUrl']\n}\n\nexport interface CmsDocumentSeoAdapters {\n readonly head: (\n input: () => {\n link: Array<{ href: string; rel: 'canonical' }>\n titleTemplate: null\n },\n ) => void\n readonly robots: (input: ComputedRef<{ readonly follow: boolean; readonly index: boolean }>) => void\n readonly schema: (input: ComputedRef<ReadonlyArray<CmsSeoSchemaNode>>) => void\n readonly seoMeta: (input: CmsSeoMetadata) => void\n}\n\nlet installedAdapters: CmsDocumentSeoAdapters | undefined\n\n/** Installs Nuxt's composables once before document page setup. */\nexport function installCmsDocumentSeoAdapters(adapters: CmsDocumentSeoAdapters): void {\n installedAdapters = adapters\n}\n\nexport function useCmsDocumentSeo(document: MaybeRefOrGetter<DeliveryDocument | null>): void {\n const adapters = installedCmsDocumentSeoAdapters()\n const
|
|
1
|
+
{"version":3,"file":"useCmsDocumentSeo.js","names":[],"sources":["../../../../../src/runtime/delivery/useCmsDocumentSeo.ts"],"sourcesContent":["import type { ResolvedSeo, SiteIdentity } from '@internal/protocol/Seo'\nimport type { ComputedRef, MaybeRefOrGetter } from 'vue'\nimport type { DeliveryDocument } from './types'\nimport { computed, toValue } from 'vue'\n\ntype ReactiveMetadataValue = () => string | undefined\n\nexport interface CmsSeoMetadata {\n readonly title: ReactiveMetadataValue\n readonly description: ReactiveMetadataValue\n readonly ogTitle: ReactiveMetadataValue\n readonly ogDescription: ReactiveMetadataValue\n readonly ogImage: ReactiveMetadataValue\n readonly ogImageAlt: ReactiveMetadataValue\n readonly robots: ReactiveMetadataValue\n}\n\ninterface CmsIdentitySchemaNode {\n readonly '@type': SiteIdentity['type']\n readonly name: string\n readonly url?: string\n readonly image?: string\n readonly logo?: string\n readonly telephone?: string\n readonly address?: NonNullable<Extract<SiteIdentity, { readonly type: 'LocalBusiness' }>['address']>\n}\n\ninterface CmsPageSchemaNode {\n readonly '@type': 'Article' | 'WebPage'\n readonly name: string\n readonly description?: string\n readonly image?: string\n readonly url?: string\n readonly headline?: string\n readonly datePublished?: string\n readonly dateModified?: string\n}\n\nexport type CmsSeoSchemaNode = CmsIdentitySchemaNode | CmsPageSchemaNode\n\ntype EffectiveSeo = Omit<ResolvedSeo, 'canonicalUrl'> & {\n readonly canonicalUrl?: ResolvedSeo['canonicalUrl']\n}\n\nexport interface CmsDocumentSeoAdapters {\n readonly head: (\n input: () => {\n htmlAttrs?: { lang: string }\n link: Array<{ href: string; rel: 'canonical' }>\n titleTemplate: null\n },\n ) => void\n readonly robots: (input: ComputedRef<{ readonly follow: boolean; readonly index: boolean }>) => void\n readonly schema: (input: ComputedRef<ReadonlyArray<CmsSeoSchemaNode>>) => void\n readonly seoMeta: (input: CmsSeoMetadata) => void\n}\n\nlet installedAdapters: CmsDocumentSeoAdapters | undefined\n\n/** Installs Nuxt's composables once before document page setup. */\nexport function installCmsDocumentSeoAdapters(adapters: CmsDocumentSeoAdapters): void {\n installedAdapters = adapters\n}\n\nexport function useCmsDocumentSeo(document: MaybeRefOrGetter<DeliveryDocument | null>): void {\n const adapters = installedCmsDocumentSeoAdapters()\n const current = computed(() => toValue(document))\n const seo = computed(() => resolvedSeo(current.value))\n\n adapters.seoMeta({\n title: () => seo.value?.title,\n description: () => seo.value?.description,\n ogTitle: () => seo.value?.socialTitle,\n ogDescription: () => seo.value?.socialDescription,\n ogImage: () => seo.value?.socialImage?.url,\n ogImageAlt: () => seo.value?.socialImage?.alt,\n robots: () =>\n seo.value ? `${seo.value.index ? 'index' : 'noindex'}, ${seo.value.follow ? 'follow' : 'nofollow'}` : undefined,\n })\n\n adapters.head(() => ({\n ...(current.value?.locale ? { htmlAttrs: { lang: current.value.locale } } : undefined),\n link: seo.value?.canonicalUrl ? [{ href: seo.value.canonicalUrl, rel: 'canonical' }] : [],\n titleTemplate: null,\n }))\n adapters.robots(\n computed(() => ({\n follow: seo.value?.follow ?? true,\n index: seo.value?.index ?? true,\n })),\n )\n adapters.schema(computed(() => (seo.value ? schemaNodes(seo.value) : [])))\n}\n\nfunction installedCmsDocumentSeoAdapters(): CmsDocumentSeoAdapters {\n if (!installedAdapters) throw new Error('The CMS document SEO adapter has not been installed.')\n\n return installedAdapters\n}\n\nfunction resolvedSeo(document: DeliveryDocument | null): EffectiveSeo | undefined {\n if (!document) return undefined\n\n if (document.resolvedSeo) return document.resolvedSeo\n\n return {\n description: document.description,\n follow: true,\n index: true,\n socialDescription: document.description,\n socialTitle: document.title,\n structuredData: { type: 'WebPage' },\n title: document.title,\n }\n}\n\nfunction schemaNodes(seo: EffectiveSeo): ReadonlyArray<CmsSeoSchemaNode> {\n const identity = seo.identity ? [identityNode(seo.identity)] : []\n\n if (!seo.structuredData) return identity\n\n const common = {\n name: seo.title,\n ...(seo.description ? { description: seo.description } : undefined),\n ...(seo.socialImage ? { image: seo.socialImage.url } : undefined),\n ...(seo.canonicalUrl ? { url: seo.canonicalUrl } : undefined),\n }\n\n if (seo.structuredData.type === 'Article') {\n return [\n ...identity,\n {\n '@type': 'Article',\n ...common,\n headline: seo.structuredData.headline ?? seo.title,\n ...(seo.structuredData.datePublished ? { datePublished: seo.structuredData.datePublished } : undefined),\n ...(seo.structuredData.dateModified ? { dateModified: seo.structuredData.dateModified } : undefined),\n },\n ]\n }\n\n return [...identity, { '@type': 'WebPage', ...common }]\n}\n\nfunction identityNode(identity: SiteIdentity): CmsIdentitySchemaNode {\n const common = {\n '@type': identity.type,\n name: identity.name,\n ...(identity.url ? { url: identity.url } : undefined),\n }\n\n switch (identity.type) {\n case 'Person':\n return { ...common, ...(identity.image ? { image: identity.image.url } : undefined) }\n case 'Organization':\n return { ...common, ...(identity.logo ? { logo: identity.logo.url } : undefined) }\n case 'LocalBusiness':\n return {\n ...common,\n ...(identity.address ? { address: identity.address } : undefined),\n ...(identity.image ? { image: identity.image.url } : undefined),\n ...(identity.logo ? { logo: identity.logo.url } : undefined),\n ...(identity.telephone ? { telephone: identity.telephone } : undefined),\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as DocumentId } from "../../scalars-B2lgGUnj.js";
|
|
2
|
-
import { t as documentForms } from "../../Forms-
|
|
2
|
+
import { t as documentForms } from "../../Forms-Dj6NuW66.js";
|
|
3
3
|
import { Predicate, Result, Schema } from "effect";
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/forms/document.ts
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { i as FormResult } from "../../Forms-CfcI3tPU.js";
|
|
2
|
-
import { i as validateFormValues } from "../../Forms-
|
|
2
|
+
import { i as validateFormValues } from "../../Forms-Dj6NuW66.js";
|
|
3
3
|
import { a as CMS_FORM_SUBMIT_PATH } from "../../HttpPaths-c9nLZ9H2.js";
|
|
4
4
|
import { Result, Schema } from "effect";
|
|
5
|
-
import { computed, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, watch } from "vue";
|
|
5
|
+
import { computed, getCurrentInstance, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, useId, watch } from "vue";
|
|
6
6
|
|
|
7
7
|
//#region src/runtime/forms/useCmsForm.ts
|
|
8
8
|
/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */
|
|
9
9
|
function useCmsForm(input, options = {}) {
|
|
10
|
+
const fieldIdPrefix = getCurrentInstance() ? useId() : "cms-form";
|
|
10
11
|
const definition = computed(() => toValue(input));
|
|
11
12
|
const steps = computed(() => definition.value.steps);
|
|
12
13
|
const fields = computed(() => steps.value.flatMap((step) => step.fields));
|
|
@@ -43,6 +44,35 @@ function useCmsForm(input, options = {}) {
|
|
|
43
44
|
errors.value = validateFormValues(fields.value, values.value);
|
|
44
45
|
return Object.keys(errors.value).length === 0;
|
|
45
46
|
}
|
|
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(" ");
|
|
63
|
+
return {
|
|
64
|
+
id,
|
|
65
|
+
name: field.id,
|
|
66
|
+
required: field.required === true,
|
|
67
|
+
"aria-invalid": invalid,
|
|
68
|
+
"aria-describedby": describedBy || void 0
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
setValue: (value) => {
|
|
72
|
+
values.value[field.id] = normalizeFormValue(field, value);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
46
76
|
function next() {
|
|
47
77
|
if (isSubmitting.value || isLastStep.value) return false;
|
|
48
78
|
const stepFields = currentStep.value?.fields ?? [];
|
|
@@ -121,6 +151,7 @@ function useCmsForm(input, options = {}) {
|
|
|
121
151
|
isSuccess: readonly(isSuccess),
|
|
122
152
|
isPreview,
|
|
123
153
|
error: readonly(error),
|
|
154
|
+
fieldState,
|
|
124
155
|
next,
|
|
125
156
|
previous,
|
|
126
157
|
validate,
|
|
@@ -128,6 +159,16 @@ function useCmsForm(input, options = {}) {
|
|
|
128
159
|
reset
|
|
129
160
|
};
|
|
130
161
|
}
|
|
162
|
+
function normalizeFormValue(field, input) {
|
|
163
|
+
if (field.type === "checkbox") return input === true;
|
|
164
|
+
if (field.type === "number") {
|
|
165
|
+
if (input === "" || input == null) return null;
|
|
166
|
+
const value = Schema.is(Schema.Finite)(input) || Schema.is(Schema.String)(input) ? Number(input) : NaN;
|
|
167
|
+
if (Number.isFinite(value)) return value;
|
|
168
|
+
return Schema.is(Schema.String)(input) ? input : null;
|
|
169
|
+
}
|
|
170
|
+
return Schema.is(Schema.String)(input) ? input : "";
|
|
171
|
+
}
|
|
131
172
|
function emptyFormValue(field) {
|
|
132
173
|
if (field.type === "checkbox") return false;
|
|
133
174
|
if (field.type === "number") return null;
|
|
@@ -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 { computed, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, watch } 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 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 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 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 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 next,\n previous,\n validate,\n submit,\n reset,\n }\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 } 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":";;;;;;;;AA8DA,SAAgB,WAAW,OAAyC,UAA6B,CAAC,GAAqB;CACrH,MAAM,gBAAgB,mBAAmB,IAAI,MAAM,IAAI;CACvD,MAAM,aAAa,eAAe,QAAQ,KAAK,CAAC;CAChD,MAAM,QAAQ,eAAe,WAAW,MAAM,KAAK;CACnD,MAAM,SAAS,eAAe,MAAM,MAAM,SAAS,SAAS,KAAK,MAAM,CAAC;CACxE,MAAM,SAAS,IAAwC,CAAC,CAAC;CACzD,MAAM,SAAS,WAAmC,CAAC,CAAC;CACpD,MAAM,YAAY,IAAI,CAAC;CACvB,MAAM,cAAc,eAAe,MAAM,MAAM,UAAU,MAAM;CAC/D,MAAM,cAAc,eAAe,UAAU,UAAU,CAAC;CACxD,MAAM,aAAa,eAAe,UAAU,UAAU,MAAM,MAAM,SAAS,CAAC;CAC5E,MAAM,eAAe,IAAI,KAAK;CAC9B,MAAM,YAAY,IAAI,KAAK;CAC3B,MAAM,YAAY,eAAe,WAAW,MAAM,OAAO;CACzD,MAAM,QAAQ,WAAmB;CACjC,IAAI;CACJ,IAAI,aAAa;CACjB,IAAI,iCAAiB,IAAI,IAAoB;CAE7C,MAAM,OAAO,MACX,aACC,MAAM,WAAW;EAChB;EACA,YAAY,MAAM;EAClB,aAAa,QAAQ;EAErB,MAAM,WACJ,QAAQ,eAAe,KAAK,cAC5B,KAAK,UAAU,OAAO,QAAQ,MAAM,KAAK,UAAU,KAAK,QAAQ,KAChE,OAAO,SAAS,KAAK;EAEvB,OAAO,QAAQ,OAAO,YACpB,KAAK,MACF,SAAS,SAAS,KAAK,MAAM,CAAC,CAC9B,KAAK,UAAU,CACd,MAAM,IACN,YAAY,eAAe,IAAI,MAAM,EAAE,MAAM,MAAM,OAC9C,OAAO,MAAM,MAAM,OAAO,OAC3B,MAAM,SAAS,aACb,QACA,MAAM,SAAS,WACb,OACA,EACV,CAAC,CACL;EACA,iBAAiB,IAAI,IAAI,KAAK,MAAM,SAAS,SAAS,KAAK,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,CAAC;EACzG,UAAU,QAAQ,KAAK,IACrB,GACA,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,QAAQ,MAAM,UAAU,MAAM,EAAE,EAAE,CAC/E;EACA,OAAO,QAAQ,CAAC;EAChB,MAAM,QAAQ;EACd,UAAU,QAAQ;CACpB,GACA;EAAE,WAAW;EAAM,MAAM;EAAM,OAAO;CAAO,CAC/C;CAEA,SAAS,WAAoB;EAC3B,OAAO,QAAQ,mBAAmB,OAAO,OAAO,OAAO,KAAK;EAE5D,OAAO,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,WAAW;CAC9C;CAEA,SAAS,WAAW,OAAqC;EACvD,MAAM,KAAK,GAAG,cAAc,GAAG,mBAAmB,MAAM,EAAE;EAE1D,OAAO;GACL;GACA,IAAI,QAAQ;IACV,OAAO,OAAO,MAAM,MAAM,OAAO,eAAe,KAAK;GACvD;GACA,IAAI,QAAQ;IACV,OAAO,OAAO,MAAM,MAAM;GAC5B;GACA,QAAQ,GAAG,GAAG;GACd,SAAS,GAAG,GAAG;GACf,IAAI,aAAa;IACf,MAAM,QAAQ,OAAO,MAAM,MAAM;IACjC,MAAM,UAA8B,QAAQ,SAAS;IAErD,MAAM,cAAc,CAAC,MAAM,OAAO,GAAG,GAAG,SAAS,QAAW,QAAQ,GAAG,GAAG,UAAU,MAAS,CAAC,CAC3F,QAAQ,SAAS,SAAS,MAAS,CAAC,CACpC,KAAK,GAAG;IAEX,OAAO;KACL;KACA,MAAM,MAAM;KACZ,UAAU,MAAM,aAAa;KAC7B,gBAAgB;KAChB,oBAAoB,eAAe;IACrC;GACF;GACA,WAAW,UAAU;IACnB,OAAO,MAAM,MAAM,MAAM,mBAAmB,OAAO,KAAK;GAC1D;EACF;CACF;CAEA,SAAS,OAAgB;EACvB,IAAI,aAAa,SAAS,WAAW,OAAO,OAAO;EACnD,MAAM,aAAa,YAAY,OAAO,UAAU,CAAC;EACjD,MAAM,SAAS,mBAAmB,YAAY,OAAO,KAAK;EAC1D,OAAO,QAAQ;GACb,GAAG,OAAO,YACR,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,MAAM,UAAU,MAAM,OAAO,EAAE,CAAC,CAC5F;GACA,GAAG;EACL;EAEA,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,QAAQ,OAAO;EACvC,UAAU;EAEV,OAAO;CACT;CAEA,SAAS,WAAiB;EACxB,IAAI,CAAC,aAAa,SAAS,CAAC,YAAY,OAAO,UAAU;CAC3D;CAEA,SAAS,QAAc;EACrB;EACA,YAAY,MAAM;EAClB,aAAa,QAAQ;EACrB,OAAO,QAAQ,OAAO,YAAY,OAAO,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,eAAe,KAAK,CAAC,CAAC,CAAC;EAChG,OAAO,QAAQ,CAAC;EAChB,MAAM,QAAQ;EACd,UAAU,QAAQ;EAClB,UAAU,QAAQ;CACpB;CAEA,eAAe,SAA2B;EACxC,IAAI,aAAa,SAAS,UAAU,OAAO,OAAO;EAClD,MAAM,QAAQ;EAEd,IAAI,CAAC,SAAS,GAAG;GACf,UAAU,QAAQ,KAAK,IACrB,GACA,MAAM,MAAM,WAAW,SAAS,KAAK,OAAO,MAAM,UAAU,OAAO,MAAM,MAAM,GAAG,CAAC,CACrF;GAEA,OAAO;EACT;EAEA,IAAI,UAAU,OAAO;GACnB,UAAU,QAAQ;GAElB,OAAO;EACT;EAEA,MAAM,oBAAoB,EAAE;EAC5B,aAAa,IAAI,gBAAgB;EACjC,aAAa,QAAQ;EAErB,IAAI;GACF,MAAM,EAAE,YAAY,UAAU,aAAa,WAAW;GAEtD,MAAM,SAAS,OAAO,QAAQ,UAAU,KAAI,CAC1C;IAAE;IAAY;IAAU;IAAU,QAAQ,EAAE,GAAG,OAAO,MAAM;GAAE,GAC9D,WAAW,MACb;GAEA,IAAI,eAAe,mBAAmB,OAAO;GAC7C,OAAO,QAAQ,EAAE,GAAG,OAAO,OAAO;GAClC,UAAU,QAAQ,OAAO,WAAW;GAEpC,IAAI,OAAO,WAAW,WACpB,UAAU,QAAQ,KAAK,IACrB,GACA,MAAM,MAAM,WAAW,SAAS,KAAK,OAAO,MAAM,UAAU,OAAO,MAAM,MAAM,GAAG,CAAC,CACrF;GAEF,IAAI,OAAO,WAAW,cAAc,OAAO,WAAW,WACpD,MAAM,QACJ,OAAO,WAAW,UACd,8DACA;GAER,OAAO,UAAU;EACnB,QAAQ;GACN,IAAI,eAAe,mBAAmB,MAAM,QAAQ;GAEpD,OAAO;EACT,UAAU;GACR,IAAI,eAAe,mBAAmB,aAAa,QAAQ;EAC7D;CACF;CAEA,IAAI,gBAAgB,GAClB,qBAAqB;EACnB;EACA,YAAY,MAAM;EAClB,KAAK;CACP,CAAC;CAEH,OAAO;EACL;EACA;EACA;EACA,QAAQ,SAAS,MAAM;EACvB;EACA,WAAW,SAAS,SAAS;EAC7B;EACA;EACA,cAAc,SAAS,YAAY;EACnC,WAAW,SAAS,SAAS;EAC7B;EACA,OAAO,SAAS,KAAK;EACrB;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAS,mBAAmB,OAAkB,OAA2D;CACvG,IAAI,MAAM,SAAS,YAAY,OAAO,UAAU;CAEhD,IAAI,MAAM,SAAS,UAAU;EAC3B,IAAI,UAAU,MAAM,SAAS,MAAM,OAAO;EAC1C,MAAM,QAAQ,OAAO,GAAG,OAAO,MAAM,CAAC,CAAC,KAAK,KAAK,OAAO,GAAG,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,IAAI;EAEnG,IAAI,OAAO,SAAS,KAAK,GAAG,OAAO;EAEnC,OAAO,OAAO,GAAG,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,QAAQ;CACnD;CAEA,OAAO,OAAO,GAAG,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,QAAQ;AACnD;AAEA,SAAS,eAAe,OAAsC;CAC5D,IAAI,MAAM,SAAS,YAAY,OAAO;CAEtC,IAAI,MAAM,SAAS,UAAU,OAAO;CAEpC,OAAO;AACT;AAEA,eAAe,KAAK,YAA4B,QAA0C;CACxF,MAAM,WAAW,MAAM,MAAM,sBAAsB;EACjD,QAAQ;EACR,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,MAAM,KAAK,UAAU,UAAU;EAC/B;CACF,CAAC;CAED,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,oBAAoB;CAEtD,OAAO,OAAO,WAAW,OAAO,oBAAoB,UAAU,CAAC,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC;AACxF"}
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
//#region src/runtime/i18n/translator.ts
|
|
2
2
|
function localeFromPath(configuration, path) {
|
|
3
|
+
return prefixedLocale(configuration, path) ?? configuration.defaultLocale;
|
|
4
|
+
}
|
|
5
|
+
/** Prefixes a site path according to the configured locale URL policy. */
|
|
6
|
+
function localePath(configuration, path, locale) {
|
|
7
|
+
const { pathname, suffix } = splitSitePath(path);
|
|
8
|
+
if (!pathname.startsWith("/") || pathname.startsWith("//")) throw new Error("A locale path must start with one slash.");
|
|
9
|
+
if (!configuration.defaultLocale) return path;
|
|
10
|
+
if (!Object.hasOwn(configuration.locales, locale)) throw new Error(`Unknown locale "${locale}".`);
|
|
11
|
+
return `${`${locale === configuration.defaultLocale && !configuration.prefixDefaultLocale ? "" : `/${locale}`}${pathname === "/" ? "" : pathname}` || "/"}${suffix}`;
|
|
12
|
+
}
|
|
13
|
+
/** Switches the locale prefix of a site path while preserving its query and fragment. */
|
|
14
|
+
function switchLocalePath(configuration, path, locale) {
|
|
15
|
+
const { pathname, suffix } = splitSitePath(path);
|
|
16
|
+
const current = prefixedLocale(configuration, pathname);
|
|
17
|
+
let unprefixed = pathname;
|
|
18
|
+
if (current !== void 0) {
|
|
19
|
+
const prefix = `/${current}`;
|
|
20
|
+
unprefixed = pathname === prefix ? "/" : pathname.slice(prefix.length);
|
|
21
|
+
}
|
|
22
|
+
return `${localePath(configuration, unprefixed, locale)}${suffix}`;
|
|
23
|
+
}
|
|
24
|
+
function prefixedLocale(configuration, path) {
|
|
3
25
|
const segment = path.split("/")[1] ?? "";
|
|
4
|
-
return Object.hasOwn(configuration.locales, segment)
|
|
26
|
+
return Object.hasOwn(configuration.locales, segment) && (segment !== configuration.defaultLocale || configuration.prefixDefaultLocale) ? segment : void 0;
|
|
27
|
+
}
|
|
28
|
+
function splitSitePath(path) {
|
|
29
|
+
const suffixIndex = path.search(/[?#]/u);
|
|
30
|
+
return {
|
|
31
|
+
pathname: suffixIndex === -1 ? path : path.slice(0, suffixIndex),
|
|
32
|
+
suffix: suffixIndex === -1 ? "" : path.slice(suffixIndex)
|
|
33
|
+
};
|
|
5
34
|
}
|
|
6
35
|
function translate(configuration, locale, key, parameters = {}, missing) {
|
|
7
36
|
function lookup(code) {
|
|
@@ -18,5 +47,5 @@ function translate(configuration, locale, key, parameters = {}, missing) {
|
|
|
18
47
|
}
|
|
19
48
|
|
|
20
49
|
//#endregion
|
|
21
|
-
export { localeFromPath, translate };
|
|
50
|
+
export { localeFromPath, localePath, switchLocalePath, translate };
|
|
22
51
|
//# sourceMappingURL=translator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translator.js","names":[],"sources":["../../../../../src/runtime/i18n/translator.ts"],"sourcesContent":["import type { CompiledCmsI18n } from '../../internal/i18n'\n\nexport function localeFromPath(configuration: CompiledCmsI18n, path: string): string {\n const segment = path.split('/')[1] ?? ''\n\n return Object.hasOwn(configuration.locales, segment) ? segment :
|
|
1
|
+
{"version":3,"file":"translator.js","names":[],"sources":["../../../../../src/runtime/i18n/translator.ts"],"sourcesContent":["import type { CompiledCmsI18n } from '../../internal/i18n'\n\nexport function localeFromPath(configuration: CompiledCmsI18n, path: string): string {\n return prefixedLocale(configuration, path) ?? configuration.defaultLocale\n}\n\n/** Prefixes a site path according to the configured locale URL policy. */\nexport function localePath(configuration: CompiledCmsI18n, path: string, locale: string): string {\n const { pathname, suffix } = splitSitePath(path)\n\n if (!pathname.startsWith('/') || pathname.startsWith('//'))\n throw new Error('A locale path must start with one slash.')\n\n if (!configuration.defaultLocale) return path\n\n if (!Object.hasOwn(configuration.locales, locale)) throw new Error(`Unknown locale \"${locale}\".`)\n\n const prefix = locale === configuration.defaultLocale && !configuration.prefixDefaultLocale ? '' : `/${locale}`\n const localized = `${prefix}${pathname === '/' ? '' : pathname}` || '/'\n\n return `${localized}${suffix}`\n}\n\n/** Switches the locale prefix of a site path while preserving its query and fragment. */\nexport function switchLocalePath(configuration: CompiledCmsI18n, path: string, locale: string): string {\n const { pathname, suffix } = splitSitePath(path)\n const current = prefixedLocale(configuration, pathname)\n let unprefixed = pathname\n\n if (current !== undefined) {\n const prefix = `/${current}`\n\n unprefixed = pathname === prefix ? '/' : pathname.slice(prefix.length)\n }\n\n return `${localePath(configuration, unprefixed, locale)}${suffix}`\n}\n\nfunction prefixedLocale(configuration: CompiledCmsI18n, path: string): string | undefined {\n const segment = path.split('/')[1] ?? ''\n\n return Object.hasOwn(configuration.locales, segment) &&\n (segment !== configuration.defaultLocale || configuration.prefixDefaultLocale)\n ? segment\n : undefined\n}\n\nfunction splitSitePath(path: string) {\n const suffixIndex = path.search(/[?#]/u)\n\n return {\n pathname: suffixIndex === -1 ? path : path.slice(0, suffixIndex),\n suffix: suffixIndex === -1 ? '' : path.slice(suffixIndex),\n }\n}\n\nexport function translate(\n configuration: CompiledCmsI18n,\n locale: string,\n key: string,\n parameters: Readonly<Record<string, string | number>> = {},\n missing?: (key: string, locale: string) => void,\n): string {\n function lookup(code: string): string | undefined {\n const messages = Object.hasOwn(configuration.locales, code) ? configuration.locales[code]?.messages : undefined\n\n return messages && Object.hasOwn(messages, key) ? messages[key] : undefined\n }\n\n let message = lookup(locale)\n\n if (message === undefined) {\n missing?.(key, locale)\n message = configuration.fallbackLocale === null ? undefined : lookup(configuration.fallbackLocale)\n }\n\n if (message === undefined) return key\n\n return message.replace(/\\{([\\w]+)\\}/gu, (placeholder: string, name: string) =>\n Object.hasOwn(parameters, name) ? String(parameters[name]) : placeholder,\n )\n}\n"],"mappings":";AAEA,SAAgB,eAAe,eAAgC,MAAsB;CACnF,OAAO,eAAe,eAAe,IAAI,KAAK,cAAc;AAC9D;;AAGA,SAAgB,WAAW,eAAgC,MAAc,QAAwB;CAC/F,MAAM,EAAE,UAAU,WAAW,cAAc,IAAI;CAE/C,IAAI,CAAC,SAAS,WAAW,GAAG,KAAK,SAAS,WAAW,IAAI,GACvD,MAAM,IAAI,MAAM,0CAA0C;CAE5D,IAAI,CAAC,cAAc,eAAe,OAAO;CAEzC,IAAI,CAAC,OAAO,OAAO,cAAc,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,mBAAmB,OAAO,GAAG;CAKhG,OAAO,GAFW,GADH,WAAW,cAAc,iBAAiB,CAAC,cAAc,sBAAsB,KAAK,IAAI,WACzE,aAAa,MAAM,KAAK,cAAc,MAE9C;AACxB;;AAGA,SAAgB,iBAAiB,eAAgC,MAAc,QAAwB;CACrG,MAAM,EAAE,UAAU,WAAW,cAAc,IAAI;CAC/C,MAAM,UAAU,eAAe,eAAe,QAAQ;CACtD,IAAI,aAAa;CAEjB,IAAI,YAAY,QAAW;EACzB,MAAM,SAAS,IAAI;EAEnB,aAAa,aAAa,SAAS,MAAM,SAAS,MAAM,OAAO,MAAM;CACvE;CAEA,OAAO,GAAG,WAAW,eAAe,YAAY,MAAM,IAAI;AAC5D;AAEA,SAAS,eAAe,eAAgC,MAAkC;CACxF,MAAM,UAAU,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM;CAEtC,OAAO,OAAO,OAAO,cAAc,SAAS,OAAO,MAChD,YAAY,cAAc,iBAAiB,cAAc,uBACxD,UACA;AACN;AAEA,SAAS,cAAc,MAAc;CACnC,MAAM,cAAc,KAAK,OAAO,OAAO;CAEvC,OAAO;EACL,UAAU,gBAAgB,KAAK,OAAO,KAAK,MAAM,GAAG,WAAW;EAC/D,QAAQ,gBAAgB,KAAK,KAAK,KAAK,MAAM,WAAW;CAC1D;AACF;AAEA,SAAgB,UACd,eACA,QACA,KACA,aAAwD,CAAC,GACzD,SACQ;CACR,SAAS,OAAO,MAAkC;EAChD,MAAM,WAAW,OAAO,OAAO,cAAc,SAAS,IAAI,IAAI,cAAc,QAAQ,KAAK,EAAE,WAAW;EAEtG,OAAO,YAAY,OAAO,OAAO,UAAU,GAAG,IAAI,SAAS,OAAO;CACpE;CAEA,IAAI,UAAU,OAAO,MAAM;CAE3B,IAAI,YAAY,QAAW;EACzB,UAAU,KAAK,MAAM;EACrB,UAAU,cAAc,mBAAmB,OAAO,SAAY,OAAO,cAAc,cAAc;CACnG;CAEA,IAAI,YAAY,QAAW,OAAO;CAElC,OAAO,QAAQ,QAAQ,kBAAkB,aAAqB,SAC5D,OAAO,OAAO,YAAY,IAAI,IAAI,OAAO,WAAW,KAAK,IAAI,WAC/D;AACF"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CmsMessageKey } from "../../I18n.js";
|
|
2
2
|
//#region src/runtime/i18n/useCmsI18n.d.ts
|
|
3
3
|
/** URL-owned locale is reactive and isolated to the current Nuxt application/request. */
|
|
4
4
|
export declare function useCmsI18n(): {
|
|
5
5
|
locale: import("vue").ComputedRef<string>;
|
|
6
|
+
localePath: (path: string, code?: string) => string;
|
|
7
|
+
switchLocalePath: (code: string, destination?: string) => string;
|
|
6
8
|
t: (key: CmsMessageKey, parameters?: Readonly<Record<string, string | number>>) => string;
|
|
7
9
|
};
|
|
8
10
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { localeFromPath, translate } from "./translator.js";
|
|
1
|
+
import { localeFromPath, localePath, switchLocalePath, translate } from "./translator.js";
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { useRoute } from "nuxt/app";
|
|
4
4
|
import configuration from "#cms/i18n";
|
|
@@ -18,8 +18,16 @@ function useCmsI18n() {
|
|
|
18
18
|
function t(key, parameters) {
|
|
19
19
|
return translate(configuration, locale.value, key, parameters, missing);
|
|
20
20
|
}
|
|
21
|
+
function localePath$1(path, code = locale.value) {
|
|
22
|
+
return localePath(configuration, path, code);
|
|
23
|
+
}
|
|
24
|
+
function switchLocalePath$1(code, destination) {
|
|
25
|
+
return destination === void 0 ? switchLocalePath(configuration, route.fullPath, code) : localePath(configuration, destination, code);
|
|
26
|
+
}
|
|
21
27
|
return {
|
|
22
28
|
locale,
|
|
29
|
+
localePath: localePath$1,
|
|
30
|
+
switchLocalePath: switchLocalePath$1,
|
|
23
31
|
t
|
|
24
32
|
};
|
|
25
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCmsI18n.js","names":[],"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 {
|
|
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"}
|
package/src/runtime/plugin.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { resolveCmsInstallation } from "../internal/configuration.js";
|
|
2
|
-
import { t as installCms } from "../installation-
|
|
2
|
+
import { t as installCms } from "../installation-CNfIriVm.js";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
import { defineNitroPlugin, useNitroApp } from "nitropack/runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/runtime/plugin.ts
|
|
7
|
-
function createInstallationPlugin(authored, authoring
|
|
7
|
+
function createInstallationPlugin(authored, authoring) {
|
|
8
8
|
return defineNitroPlugin((nitro) => {
|
|
9
9
|
if (nitro.cmsInstallation) throw new Error("The CMS installation is already registered with Nitro.");
|
|
10
|
-
const configuration = resolveCmsInstallation(authored, authoring
|
|
10
|
+
const configuration = resolveCmsInstallation(authored, authoring);
|
|
11
11
|
const installation = Effect.runPromise(installCms(configuration));
|
|
12
12
|
nitro.cmsInstallation = installation;
|
|
13
13
|
installation.catch((cause) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/runtime/plugin.ts"],"sourcesContent":["import type { CmsInstallation } from '@internal/platform-node/Installation'\nimport type {
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/runtime/plugin.ts"],"sourcesContent":["import type { CmsInstallation } from '@internal/platform-node/Installation'\nimport type { AuthoringCatalog } from '@internal/protocol/Configuration'\nimport type { CmsConfiguration } from '../Configuration'\nimport { Effect } from 'effect'\nimport { defineNitroPlugin, useNitroApp } from 'nitropack/runtime'\nimport { resolveCmsInstallation } from '../internal/configuration'\nimport { installCms } from './installation'\n\ndeclare module 'nitropack/types' {\n interface NitroApp {\n cmsInstallation?: Promise<CmsInstallation>\n }\n}\n\nexport function createInstallationPlugin(authored: CmsConfiguration, authoring: AuthoringCatalog) {\n return defineNitroPlugin((nitro) => {\n if (nitro.cmsInstallation) throw new Error('The CMS installation is already registered with Nitro.')\n const configuration = resolveCmsInstallation(authored, authoring)\n const installation = Effect.runPromise(installCms(configuration))\n nitro.cmsInstallation = installation\n\n void installation.catch((cause: unknown) => {\n nitro.captureError(cause instanceof Error ? cause : new Error(String(cause)), {\n fatal: true,\n tags: ['cms'],\n })\n })\n nitro.hooks.hook('close', () =>\n installation\n .then(\n (current) => current.close(),\n () => undefined,\n )\n .finally(() => {\n if (nitro.cmsInstallation === installation) nitro.cmsInstallation = undefined\n }),\n )\n })\n}\n\nexport function useCmsInstallation(): Promise<CmsInstallation> {\n const installation = useNitroApp().cmsInstallation\n\n if (!installation) throw new Error('The CMS installation has not been registered with Nitro.')\n\n return installation\n}\n"],"mappings":";;;;;;AAcA,SAAgB,yBAAyB,UAA4B,WAA6B;CAChG,OAAO,mBAAmB,UAAU;EAClC,IAAI,MAAM,iBAAiB,MAAM,IAAI,MAAM,wDAAwD;EACnG,MAAM,gBAAgB,uBAAuB,UAAU,SAAS;EAChE,MAAM,eAAe,OAAO,WAAW,WAAW,aAAa,CAAC;EAChE,MAAM,kBAAkB;EAExB,AAAK,aAAa,OAAO,UAAmB;GAC1C,MAAM,aAAa,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,GAAG;IAC5E,OAAO;IACP,MAAM,CAAC,KAAK;GACd,CAAC;EACH,CAAC;EACD,MAAM,MAAM,KAAK,eACf,aACG,MACE,YAAY,QAAQ,MAAM,SACrB,MACR,CAAC,CACA,cAAc;GACb,IAAI,MAAM,oBAAoB,cAAc,MAAM,kBAAkB;EACtE,CAAC,CACL;CACF,CAAC;AACH;AAEA,SAAgB,qBAA+C;CAC7D,MAAM,eAAe,YAAY,CAAC,CAAC;CAEnC,IAAI,CAAC,cAAc,MAAM,IAAI,MAAM,0DAA0D;CAE7F,OAAO;AACT"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as EditorNodeId, l as RevisionNumber, r as DocumentId } from "../../scalars-B2lgGUnj.js";
|
|
2
|
-
import {
|
|
3
|
-
import { r as PreviewIntentId } from "../../models-
|
|
2
|
+
import { Et as RequestId } from "../../models-Bah5B3bT.js";
|
|
3
|
+
import { r as PreviewIntentId } from "../../models-B4IoTmp7.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-
|
|
3
|
-
import { n as readPreviewLocation, r as withPreviewLocation } from "../../location-
|
|
2
|
+
import { t as openSitePreviewConnection } from "../../connection-CBAy2qGy.js";
|
|
3
|
+
import { n as readPreviewLocation, r as withPreviewLocation } from "../../location-BTqdfIzX.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-
|
|
7
|
+
import { t as createStudioPreviewStore } from "../../store-b2CSXgMt.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-
|
|
2
|
+
import { t as createStudioPreviewStore } from "../../store-b2CSXgMt.js";
|
|
3
3
|
|
|
4
4
|
export { createStudioPreviewStore, documentPreviewStoreKey };
|
package/src/runtime/sitemap.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { q as SitemapEntry } from "../models-Bah5B3bT.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";
|
|
@@ -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-
|
|
3
|
-
import {
|
|
2
|
+
import { f as mutableJson, p as mutableJsonObject } from "./Forms-Dj6NuW66.js";
|
|
3
|
+
import { Ct as CollectionName, n as CmsMarkdownDocument } from "./models-Bah5B3bT.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-
|
|
226
|
+
//# sourceMappingURL=store-b2CSXgMt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-DjJs3I7k.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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"}
|
|
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":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ as e, $t as t, Ct as n, Ft as r, J as ee, K as i, Mt as a, Q as o, Tt as te, Z as s, an as c, et as l, it as u, ot as d, pt as f, sn as p, tt as m, un as h, zt as g } from "./editor-Bzlh3zXt.js";
|
|
2
|
-
import { A as _, F as v, I as y, N as b, P as x, R as S, a as ne, n as re, nr as C, pr as ie, r as ae, rr as oe, t as w } from "./documentPlanning-
|
|
2
|
+
import { A as _, F as v, I as y, N as b, P as x, R as S, a as ne, n as re, nr as C, pr as ie, r as ae, rr as oe, t as w } from "./documentPlanning-DRErYmBU.js";
|
|
3
3
|
//#region src/documents/CreateDocumentDialog.vue?vue&type=script&setup=true&lang.ts
|
|
4
4
|
var se = { key: 2 }, ce = { class: "grid grid-flow-col auto-cols-fr overflow-x-auto rounded-md border border-default" }, T = ["title", "onClick"], E = { class: "block truncate" }, le = {
|
|
5
5
|
key: 0,
|