@phtngyn/cms 0.1.0-beta.0 → 0.1.0-beta.2
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 +260 -6
- package/package.json +31 -16
- package/src/Authoring.d.ts +13 -1
- package/src/Configuration-Br7tE9Qt.d.ts +68 -0
- package/src/{AuthoringSchema-BQ5kbhVB.js → Configuration-CA_jvQKG.js} +599 -492
- package/src/Configuration-CA_jvQKG.js.map +1 -0
- package/src/Configuration.d.ts +2 -44
- package/src/Configuration.js +0 -1
- package/src/Configuration.js.map +1 -1
- package/src/{DocumentEngine-Da0kWotL.js → DocumentEngine-CgiBQU4g.js} +110 -84
- package/src/DocumentEngine-CgiBQU4g.js.map +1 -0
- package/src/DocumentModel-BB9igGC7.d.ts +34 -0
- package/src/DocumentModel.d.ts +2 -30
- package/src/DocumentModel.js +13 -3
- package/src/DocumentModel.js.map +1 -1
- package/src/Forms-BsJMev5_.d.ts +74 -0
- package/src/Forms-CfcI3tPU.js +79 -0
- package/src/Forms-CfcI3tPU.js.map +1 -0
- package/src/Forms-DxbkU3_5.js +367 -0
- package/src/Forms-DxbkU3_5.js.map +1 -0
- package/src/Forms.d.ts +35 -0
- package/src/Forms.js +13 -0
- package/src/Forms.js.map +1 -0
- package/src/HttpPaths-c9nLZ9H2.js +21 -0
- package/src/HttpPaths-c9nLZ9H2.js.map +1 -0
- package/src/I18n-DZK4CkJF.d.ts +21 -0
- package/src/I18n.d.ts +2 -0
- package/src/I18n.js +1 -0
- package/src/Module.js +78 -81
- package/src/Module.js.map +1 -1
- package/src/S3MediaObjects-JKMAWyVB.js +2664 -0
- package/src/S3MediaObjects-JKMAWyVB.js.map +1 -0
- package/src/Seed.d.ts +6 -0
- package/src/Seed.js +34 -0
- package/src/Seed.js.map +1 -0
- package/src/Seo-402YumpT.d.ts +198 -0
- package/src/{connection-ZGtL54qY.js → connection-B-iz0Y9Y.js} +5 -7
- package/src/connection-B-iz0Y9Y.js.map +1 -0
- package/src/{installation-BNKaVjni.js → installation-DgF2M1gL.js} +1162 -2147
- package/src/installation-DgF2M1gL.js.map +1 -0
- package/src/internal/authoring-catalog.js +153 -0
- package/src/internal/authoring-catalog.js.map +1 -0
- package/src/internal/authoring-compiler.js +2 -2
- package/src/internal/authoring-compiler.js.map +1 -1
- package/src/internal/authoring-metadata.js +68 -49
- package/src/internal/authoring-metadata.js.map +1 -1
- package/src/internal/cms-config.js +0 -1
- package/src/internal/cms-config.js.map +1 -1
- package/src/internal/configuration.js +25 -13
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/document-model.js +66 -20
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/form-capabilities.js +12 -0
- package/src/internal/form-capabilities.js.map +1 -0
- package/src/internal/i18n.js +47 -0
- package/src/internal/i18n.js.map +1 -0
- package/src/internal/studio-app.js +66 -0
- package/src/internal/studio-app.js.map +1 -0
- package/src/location-CFKTeK1K.js +35 -0
- package/src/location-CFKTeK1K.js.map +1 -0
- package/src/{metadata-Czvi3E4K.js → metadata-BEZPWh-3.js} +3 -72
- package/src/metadata-BEZPWh-3.js.map +1 -0
- package/src/{models-DS5ClMsH.js → models-BWm1pTAf.js} +9 -31
- package/src/models-BWm1pTAf.js.map +1 -0
- package/src/models-DwYioyNV.js +726 -0
- package/src/models-DwYioyNV.js.map +1 -0
- package/src/runtime/blocks.js +30 -0
- package/src/runtime/blocks.js.map +1 -0
- package/src/runtime/collaboration.js +9 -4
- package/src/runtime/collaboration.js.map +1 -1
- package/src/runtime/delivery/DocumentRenderer.js +10 -4
- package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
- package/src/runtime/delivery/blocks.js +8 -0
- package/src/runtime/delivery/blocks.js.map +1 -0
- package/src/runtime/delivery/context.js +12 -0
- package/src/runtime/delivery/context.js.map +1 -0
- package/src/runtime/delivery/document-page.js +14 -12
- package/src/runtime/delivery/document-page.js.map +1 -1
- package/src/runtime/delivery/document.js +21 -3
- package/src/runtime/delivery/document.js.map +1 -1
- package/src/runtime/delivery/error.js +11 -0
- package/src/runtime/delivery/error.js.map +1 -0
- package/src/runtime/delivery/plugin.js +41 -0
- package/src/runtime/delivery/plugin.js.map +1 -0
- package/src/runtime/delivery/types.d.ts +5 -0
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +56 -0
- package/src/runtime/delivery/useCmsDocumentSeo.js +99 -0
- package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -0
- package/src/runtime/delivery/useDocument.js +5 -2
- package/src/runtime/delivery/useDocument.js.map +1 -1
- package/src/runtime/delivery/useDocumentQuery.js +5 -2
- package/src/runtime/delivery/useDocumentQuery.js.map +1 -1
- package/src/runtime/forms/document.js +38 -0
- package/src/runtime/forms/document.js.map +1 -0
- package/src/runtime/forms/useCmsForm.js +149 -0
- package/src/runtime/forms/useCmsForm.js.map +1 -0
- package/src/runtime/i18n/translator.js +22 -0
- package/src/runtime/i18n/translator.js.map +1 -0
- package/src/runtime/i18n/useCmsI18n.d.ts +9 -0
- package/src/runtime/i18n/useCmsI18n.js +29 -0
- package/src/runtime/i18n/useCmsI18n.js.map +1 -0
- 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/comark-document.js +0 -1
- package/src/runtime/preview/comark-document.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +37 -11
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/overlay.js +65 -0
- package/src/runtime/preview/overlay.js.map +1 -0
- package/src/runtime/preview/plugin.client.js +59 -61
- package/src/runtime/preview/plugin.client.js.map +1 -1
- package/src/runtime/preview/preview.css +72 -4
- package/src/runtime/preview/protocol.js.map +1 -1
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/preview/targets.js +0 -1
- package/src/runtime/preview/targets.js.map +1 -1
- package/src/runtime/sitemap-entries.js +17 -0
- package/src/runtime/sitemap-entries.js.map +1 -0
- package/src/runtime/sitemap.js +24 -0
- package/src/runtime/sitemap.js.map +1 -0
- package/src/runtime/studio-app.js +5 -1
- package/src/runtime/studio-app.js.map +1 -1
- package/src/runtime/studio-entry.js +36 -0
- package/src/runtime/studio-entry.js.map +1 -0
- package/src/runtime/studio-navigation.js +11 -0
- package/src/runtime/studio-navigation.js.map +1 -0
- package/src/scalars-B2lgGUnj.js +26 -0
- package/src/scalars-B2lgGUnj.js.map +1 -0
- package/src/{store-Nl4uxEXx.js → store-DjJs3I7k.js} +12 -7
- package/src/store-DjJs3I7k.js.map +1 -0
- package/studio/CreateDocumentDialog-CTeIFlPb.js +256 -0
- package/studio/collaboration-DcK2F6v9.js +4566 -0
- package/studio/documentPlanning-Bfv-d7OU.js +29820 -0
- package/studio/dom-to-image-more.min-D6jGGdrW.js +877 -0
- package/studio/editor-Bzlh3zXt.js +30827 -0
- package/studio/host.css +3 -0
- package/studio/host.js +46614 -0
- package/studio/rolldown-runtime-B0aSnxlc.js +20 -0
- package/dist/studio/assets/ActivityEntryRow-D--fRvWI.js +0 -1
- package/dist/studio/assets/ActivityView-D-XBBUHb.js +0 -1
- package/dist/studio/assets/CreateDocumentDialog-CH8UH1QM.js +0 -1
- package/dist/studio/assets/DocumentsView-CxRpmAxt.js +0 -34
- package/dist/studio/assets/DropdownMenu-BSb1l7fr.js +0 -1
- package/dist/studio/assets/Input-DVao38h7.js +0 -3
- package/dist/studio/assets/MediaView-BHrPIjxB.js +0 -1
- package/dist/studio/assets/Modal-VNrXGa5C.js +0 -1
- package/dist/studio/assets/OverviewView-DfP6-mLZ.js +0 -1
- package/dist/studio/assets/Select-BJZIs9sY.js +0 -1
- package/dist/studio/assets/SettingsView-CerHe-ua.js +0 -1
- package/dist/studio/assets/Skeleton-CWJNi3nS.js +0 -1
- package/dist/studio/assets/StudioPageHeader-DP9HDAF2.js +0 -1
- package/dist/studio/assets/UsersView-cP3REkH2.js +0 -1
- package/dist/studio/assets/collaboration-BLnCzfvV.js +0 -4
- package/dist/studio/assets/context-dY4fNbn3.js +0 -1
- package/dist/studio/assets/editor-CE07wW83.js +0 -137
- package/dist/studio/assets/gateway-BAyQgCse.js +0 -10
- package/dist/studio/assets/index-CjoaPLhZ.js +0 -28
- package/dist/studio/assets/index-s2rPqCmP.css +0 -2
- package/dist/studio/assets/render-BkxbK2St.js +0 -83
- package/dist/studio/assets/rolldown-runtime-DK3Fl9T5.js +0 -1
- package/dist/studio/assets/useMediaLibrary-D7qR7aBf.js +0 -1
- package/dist/studio/index.html +0 -76
- package/src/AuthoringSchema-BQ5kbhVB.js.map +0 -1
- package/src/Configuration-BGYFD2N1.js +0 -150
- package/src/Configuration-BGYFD2N1.js.map +0 -1
- package/src/DocumentEngine-Da0kWotL.js.map +0 -1
- package/src/HttpPaths-86qLGB90.js +0 -15
- package/src/HttpPaths-86qLGB90.js.map +0 -1
- package/src/StudioHttp-BTLLooh0.js +0 -916
- package/src/StudioHttp-BTLLooh0.js.map +0 -1
- package/src/connection-ZGtL54qY.js.map +0 -1
- package/src/installation-BNKaVjni.js.map +0 -1
- package/src/internal/component-metadata.js +0 -37
- package/src/internal/component-metadata.js.map +0 -1
- package/src/metadata-Czvi3E4K.js.map +0 -1
- package/src/models-Citx8jBi.js +0 -306
- package/src/models-Citx8jBi.js.map +0 -1
- package/src/models-DS5ClMsH.js.map +0 -1
- package/src/store-Nl4uxEXx.js.map +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { computed, toValue } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/delivery/useCmsDocumentSeo.ts
|
|
4
|
+
let installedAdapters;
|
|
5
|
+
/** Installs Nuxt's composables once before document page setup. */
|
|
6
|
+
function installCmsDocumentSeoAdapters(adapters) {
|
|
7
|
+
installedAdapters = adapters;
|
|
8
|
+
}
|
|
9
|
+
function useCmsDocumentSeo(document) {
|
|
10
|
+
const adapters = installedCmsDocumentSeoAdapters();
|
|
11
|
+
const seo = computed(() => resolvedSeo(toValue(document)));
|
|
12
|
+
adapters.seoMeta({
|
|
13
|
+
title: () => seo.value?.title,
|
|
14
|
+
description: () => seo.value?.description,
|
|
15
|
+
ogTitle: () => seo.value?.socialTitle,
|
|
16
|
+
ogDescription: () => seo.value?.socialDescription,
|
|
17
|
+
ogImage: () => seo.value?.socialImage?.url,
|
|
18
|
+
ogImageAlt: () => seo.value?.socialImage?.alt,
|
|
19
|
+
robots: () => seo.value ? `${seo.value.index ? "index" : "noindex"}, ${seo.value.follow ? "follow" : "nofollow"}` : void 0
|
|
20
|
+
});
|
|
21
|
+
adapters.head(() => ({
|
|
22
|
+
link: seo.value?.canonicalUrl ? [{
|
|
23
|
+
href: seo.value.canonicalUrl,
|
|
24
|
+
rel: "canonical"
|
|
25
|
+
}] : [],
|
|
26
|
+
titleTemplate: null
|
|
27
|
+
}));
|
|
28
|
+
adapters.robots(computed(() => ({
|
|
29
|
+
follow: seo.value?.follow ?? true,
|
|
30
|
+
index: seo.value?.index ?? true
|
|
31
|
+
})));
|
|
32
|
+
adapters.schema(computed(() => seo.value ? schemaNodes(seo.value) : []));
|
|
33
|
+
}
|
|
34
|
+
function installedCmsDocumentSeoAdapters() {
|
|
35
|
+
if (!installedAdapters) throw new Error("The CMS document SEO adapter has not been installed.");
|
|
36
|
+
return installedAdapters;
|
|
37
|
+
}
|
|
38
|
+
function resolvedSeo(document) {
|
|
39
|
+
if (!document) return void 0;
|
|
40
|
+
if (document.resolvedSeo) return document.resolvedSeo;
|
|
41
|
+
return {
|
|
42
|
+
description: document.description,
|
|
43
|
+
follow: true,
|
|
44
|
+
index: true,
|
|
45
|
+
socialDescription: document.description,
|
|
46
|
+
socialTitle: document.title,
|
|
47
|
+
structuredData: { type: "WebPage" },
|
|
48
|
+
title: document.title
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function schemaNodes(seo) {
|
|
52
|
+
const identity = seo.identity ? [identityNode(seo.identity)] : [];
|
|
53
|
+
if (!seo.structuredData) return identity;
|
|
54
|
+
const common = {
|
|
55
|
+
name: seo.title,
|
|
56
|
+
...seo.description ? { description: seo.description } : void 0,
|
|
57
|
+
...seo.socialImage ? { image: seo.socialImage.url } : void 0,
|
|
58
|
+
...seo.canonicalUrl ? { url: seo.canonicalUrl } : void 0
|
|
59
|
+
};
|
|
60
|
+
if (seo.structuredData.type === "Article") return [...identity, {
|
|
61
|
+
"@type": "Article",
|
|
62
|
+
...common,
|
|
63
|
+
headline: seo.structuredData.headline ?? seo.title,
|
|
64
|
+
...seo.structuredData.datePublished ? { datePublished: seo.structuredData.datePublished } : void 0,
|
|
65
|
+
...seo.structuredData.dateModified ? { dateModified: seo.structuredData.dateModified } : void 0
|
|
66
|
+
}];
|
|
67
|
+
return [...identity, {
|
|
68
|
+
"@type": "WebPage",
|
|
69
|
+
...common
|
|
70
|
+
}];
|
|
71
|
+
}
|
|
72
|
+
function identityNode(identity) {
|
|
73
|
+
const common = {
|
|
74
|
+
"@type": identity.type,
|
|
75
|
+
name: identity.name,
|
|
76
|
+
...identity.url ? { url: identity.url } : void 0
|
|
77
|
+
};
|
|
78
|
+
switch (identity.type) {
|
|
79
|
+
case "Person": return {
|
|
80
|
+
...common,
|
|
81
|
+
...identity.image ? { image: identity.image.url } : void 0
|
|
82
|
+
};
|
|
83
|
+
case "Organization": return {
|
|
84
|
+
...common,
|
|
85
|
+
...identity.logo ? { logo: identity.logo.url } : void 0
|
|
86
|
+
};
|
|
87
|
+
case "LocalBusiness": return {
|
|
88
|
+
...common,
|
|
89
|
+
...identity.address ? { address: identity.address } : void 0,
|
|
90
|
+
...identity.image ? { image: identity.image.url } : void 0,
|
|
91
|
+
...identity.logo ? { logo: identity.logo.url } : void 0,
|
|
92
|
+
...identity.telephone ? { telephone: identity.telephone } : void 0
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//#endregion
|
|
98
|
+
export { installCmsDocumentSeoAdapters, useCmsDocumentSeo };
|
|
99
|
+
//# sourceMappingURL=useCmsDocumentSeo.js.map
|
|
@@ -0,0 +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 seo = computed(() => resolvedSeo(toValue(document)))\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 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,14 +1,17 @@
|
|
|
1
|
-
import { r as CMS_DELIVERY_READ_PATH } from "../../HttpPaths-
|
|
1
|
+
import { c as CMS_PREVIEW_READ_PATH, r as CMS_DELIVERY_READ_PATH } from "../../HttpPaths-c9nLZ9H2.js";
|
|
2
|
+
import { usePreviewDelivery } from "./context.js";
|
|
2
3
|
import { computed, toValue } from "vue";
|
|
3
4
|
import { useFetch } from "nuxt/app";
|
|
4
5
|
|
|
5
6
|
//#region src/runtime/delivery/useDocument.ts
|
|
6
7
|
function useDocument(path) {
|
|
8
|
+
const preview = usePreviewDelivery();
|
|
9
|
+
const endpoint = computed(() => preview.value ? CMS_PREVIEW_READ_PATH : CMS_DELIVERY_READ_PATH);
|
|
7
10
|
const body = computed(() => ({
|
|
8
11
|
kind: "path",
|
|
9
12
|
path: toValue(path)
|
|
10
13
|
}));
|
|
11
|
-
return useFetch(
|
|
14
|
+
return useFetch(endpoint, {
|
|
12
15
|
body,
|
|
13
16
|
default: () => null,
|
|
14
17
|
method: "POST"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocument.js","names":[],"sources":["../../../../../src/runtime/delivery/useDocument.ts"],"sourcesContent":["import { useFetch } from 'nuxt/app'\nimport type { MaybeRefOrGetter } from 'vue'\nimport { computed, toValue } from 'vue'\nimport { CMS_DELIVERY_READ_PATH } from '@internal/protocol/HttpPaths'\nimport type { DeliveryDocument } from './types'\n\nexport function useDocument(path: MaybeRefOrGetter<string>) {\n const body = computed(() => ({ kind: 'path' as const, path: toValue(path) }))\n return useFetch<DeliveryDocument | null>(
|
|
1
|
+
{"version":3,"file":"useDocument.js","names":[],"sources":["../../../../../src/runtime/delivery/useDocument.ts"],"sourcesContent":["import { useFetch } from 'nuxt/app'\nimport { usePreviewDelivery } from './context'\nimport type { MaybeRefOrGetter } from 'vue'\nimport { computed, toValue } from 'vue'\nimport { CMS_DELIVERY_READ_PATH, CMS_PREVIEW_READ_PATH } from '@internal/protocol/HttpPaths'\nimport type { DeliveryDocument } from './types'\n\nexport function useDocument(path: MaybeRefOrGetter<string>) {\n const preview = usePreviewDelivery()\n const endpoint = computed(() => (preview.value ? CMS_PREVIEW_READ_PATH : CMS_DELIVERY_READ_PATH))\n const body = computed(() => ({ kind: 'path' as const, path: toValue(path) }))\n\n return useFetch<DeliveryDocument | null>(endpoint, {\n body,\n default: () => null,\n method: 'POST',\n })\n}\n"],"mappings":";;;;;;AAOA,SAAgB,YAAY,MAAgC;CAC1D,MAAM,UAAU,mBAAmB;CACnC,MAAM,WAAW,eAAgB,QAAQ,QAAQ,wBAAwB,sBAAuB;CAChG,MAAM,OAAO,gBAAgB;EAAE,MAAM;EAAiB,MAAM,QAAQ,IAAI;CAAE,EAAE;CAE5E,OAAO,SAAkC,UAAU;EACjD;EACA,eAAe;EACf,QAAQ;CACV,CAAC;AACH"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { n as CMS_DELIVERY_QUERY_PATH } from "../../HttpPaths-
|
|
1
|
+
import { n as CMS_DELIVERY_QUERY_PATH, s as CMS_PREVIEW_QUERY_PATH } from "../../HttpPaths-c9nLZ9H2.js";
|
|
2
|
+
import { usePreviewDelivery } from "./context.js";
|
|
2
3
|
import { computed, toValue } from "vue";
|
|
3
4
|
import { useFetch } from "nuxt/app";
|
|
4
5
|
|
|
5
6
|
//#region src/runtime/delivery/useDocumentQuery.ts
|
|
6
7
|
function useDocumentQuery(query) {
|
|
8
|
+
const preview = usePreviewDelivery();
|
|
9
|
+
const endpoint = computed(() => preview.value ? CMS_PREVIEW_QUERY_PATH : CMS_DELIVERY_QUERY_PATH);
|
|
7
10
|
const body = computed(() => {
|
|
8
11
|
const value = toValue(query);
|
|
9
12
|
return {
|
|
@@ -11,7 +14,7 @@ function useDocumentQuery(query) {
|
|
|
11
14
|
sort: value.sort === void 0 ? void 0 : Array.isArray(value.sort) ? value.sort : [value.sort]
|
|
12
15
|
};
|
|
13
16
|
});
|
|
14
|
-
return useFetch(
|
|
17
|
+
return useFetch(endpoint, {
|
|
15
18
|
body,
|
|
16
19
|
default: () => ({
|
|
17
20
|
items: [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentQuery.js","names":[],"sources":["../../../../../src/runtime/delivery/useDocumentQuery.ts"],"sourcesContent":["import { useFetch } from 'nuxt/app'\nimport type { MaybeRefOrGetter } from 'vue'\nimport { computed, toValue } from 'vue'\nimport { CMS_DELIVERY_QUERY_PATH } from '@internal/protocol/HttpPaths'\nimport type { DeliveryDocumentPage, DeliveryDocumentQuery } from './types'\n\nexport type { DeliveryDocumentQuery, DeliveryDocumentQuerySort } from './types'\n\nexport function useDocumentQuery(query: MaybeRefOrGetter<DeliveryDocumentQuery>) {\n const body = computed(() => {\n const value = toValue(query)\n return {\n ...value,\n sort: value.sort === undefined ? undefined : Array.isArray(value.sort) ? value.sort : [value.sort],\n }\n })\n return useFetch<DeliveryDocumentPage>(
|
|
1
|
+
{"version":3,"file":"useDocumentQuery.js","names":[],"sources":["../../../../../src/runtime/delivery/useDocumentQuery.ts"],"sourcesContent":["import { useFetch } from 'nuxt/app'\nimport { usePreviewDelivery } from './context'\nimport type { MaybeRefOrGetter } from 'vue'\nimport { computed, toValue } from 'vue'\nimport { CMS_DELIVERY_QUERY_PATH, CMS_PREVIEW_QUERY_PATH } from '@internal/protocol/HttpPaths'\nimport type { DeliveryDocumentPage, DeliveryDocumentQuery } from './types'\n\nexport type { DeliveryDocumentQuery, DeliveryDocumentQuerySort } from './types'\n\nexport function useDocumentQuery(query: MaybeRefOrGetter<DeliveryDocumentQuery>) {\n const preview = usePreviewDelivery()\n const endpoint = computed(() => (preview.value ? CMS_PREVIEW_QUERY_PATH : CMS_DELIVERY_QUERY_PATH))\n\n const body = computed(() => {\n const value = toValue(query)\n\n return {\n ...value,\n sort: value.sort === undefined ? undefined : Array.isArray(value.sort) ? value.sort : [value.sort],\n }\n })\n\n return useFetch<DeliveryDocumentPage>(endpoint, {\n body,\n default: () => ({ items: [], total: 0 }),\n method: 'POST',\n })\n}\n"],"mappings":";;;;;;AASA,SAAgB,iBAAiB,OAAgD;CAC/E,MAAM,UAAU,mBAAmB;CACnC,MAAM,WAAW,eAAgB,QAAQ,QAAQ,yBAAyB,uBAAwB;CAElG,MAAM,OAAO,eAAe;EAC1B,MAAM,QAAQ,QAAQ,KAAK;EAE3B,OAAO;GACL,GAAG;GACH,MAAM,MAAM,SAAS,SAAY,SAAY,MAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,MAAM,IAAI;EACnG;CACF,CAAC;CAED,OAAO,SAA+B,UAAU;EAC9C;EACA,gBAAgB;GAAE,OAAO,CAAC;GAAG,OAAO;EAAE;EACtC,QAAQ;CACV,CAAC;AACH"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { r as DocumentId } from "../../scalars-B2lgGUnj.js";
|
|
2
|
+
import { t as documentForms } from "../../Forms-DxbkU3_5.js";
|
|
3
|
+
import { Predicate, Result, Schema } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/forms/document.ts
|
|
6
|
+
/** Both ordinary rendering and Comark's live preview cache receive the same derived form props. */
|
|
7
|
+
function prepareFormDocument(value, components, preview) {
|
|
8
|
+
if (!components.some((component) => component.authoring.form)) return value;
|
|
9
|
+
const definitions = documentForms({
|
|
10
|
+
id: DocumentId.make(value.id),
|
|
11
|
+
body: value.body
|
|
12
|
+
}, components, preview || value.draft);
|
|
13
|
+
const visit = (nodes, parent) => nodes.map((node, index) => {
|
|
14
|
+
if (Predicate.isString(node) || node[0] === null) return node;
|
|
15
|
+
const [tag, attributes, ...children] = node;
|
|
16
|
+
const path = [...parent, index];
|
|
17
|
+
const form = definitions.find((candidate) => JSON.stringify(candidate.nodePath) === JSON.stringify(path));
|
|
18
|
+
return [
|
|
19
|
+
tag,
|
|
20
|
+
{
|
|
21
|
+
...attributes,
|
|
22
|
+
...form ? { cmsForm: Result.getOrThrow(Schema.decodeUnknownResult(Schema.JsonObject)(form)) } : void 0
|
|
23
|
+
},
|
|
24
|
+
...visit(children, path)
|
|
25
|
+
];
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
...value,
|
|
29
|
+
body: {
|
|
30
|
+
...value.body,
|
|
31
|
+
nodes: visit(value.body.nodes, [])
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { prepareFormDocument };
|
|
38
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","names":[],"sources":["../../../../../src/runtime/forms/document.ts"],"sourcesContent":["import type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { DeliveryDocument, DeliveryMarkdownNode } from '../delivery/types'\nimport { DocumentId } from '@internal/protocol/Documents'\nimport { documentForms } from '@internal/document/Forms'\nimport { Result, Predicate, Schema } from 'effect'\n\n/** Both ordinary rendering and Comark's live preview cache receive the same derived form props. */\nexport function prepareFormDocument(\n value: DeliveryDocument,\n components: ReadonlyArray<ComponentDefinition>,\n preview: boolean,\n): DeliveryDocument {\n if (!components.some((component) => component.authoring.form)) return value\n\n const definitions = documentForms(\n { id: DocumentId.make(value.id), body: value.body },\n components,\n preview || value.draft,\n )\n\n const visit = (nodes: ReadonlyArray<DeliveryMarkdownNode>, parent: number[]): ReadonlyArray<DeliveryMarkdownNode> =>\n nodes.map((node, index) => {\n if (Predicate.isString(node) || node[0] === null) return node\n const [tag, attributes, ...children] = node\n const path = [...parent, index]\n const form = definitions.find((candidate) => JSON.stringify(candidate.nodePath) === JSON.stringify(path))\n\n return [\n tag,\n {\n ...attributes,\n ...(form ? { cmsForm: Result.getOrThrow(Schema.decodeUnknownResult(Schema.JsonObject)(form)) } : undefined),\n },\n ...visit(children, path),\n ]\n })\n\n return { ...value, body: { ...value.body, nodes: visit(value.body.nodes, []) } }\n}\n"],"mappings":";;;;;;AAOA,SAAgB,oBACd,OACA,YACA,SACkB;CAClB,IAAI,CAAC,WAAW,MAAM,cAAc,UAAU,UAAU,IAAI,GAAG,OAAO;CAEtE,MAAM,cAAc,cAClB;EAAE,IAAI,WAAW,KAAK,MAAM,EAAE;EAAG,MAAM,MAAM;CAAK,GAClD,YACA,WAAW,MAAM,KACnB;CAEA,MAAM,SAAS,OAA4C,WACzD,MAAM,KAAK,MAAM,UAAU;EACzB,IAAI,UAAU,SAAS,IAAI,KAAK,KAAK,OAAO,MAAM,OAAO;EACzD,MAAM,CAAC,KAAK,YAAY,GAAG,YAAY;EACvC,MAAM,OAAO,CAAC,GAAG,QAAQ,KAAK;EAC9B,MAAM,OAAO,YAAY,MAAM,cAAc,KAAK,UAAU,UAAU,QAAQ,MAAM,KAAK,UAAU,IAAI,CAAC;EAExG,OAAO;GACL;GACA;IACE,GAAG;IACH,GAAI,OAAO,EAAE,SAAS,OAAO,WAAW,OAAO,oBAAoB,OAAO,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI;GACnG;GACA,GAAG,MAAM,UAAU,IAAI;EACzB;CACF,CAAC;CAEH,OAAO;EAAE,GAAG;EAAO,MAAM;GAAE,GAAG,MAAM;GAAM,OAAO,MAAM,MAAM,KAAK,OAAO,CAAC,CAAC;EAAE;CAAE;AACjF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { i as FormResult } from "../../Forms-CfcI3tPU.js";
|
|
2
|
+
import { i as validateFormValues } from "../../Forms-DxbkU3_5.js";
|
|
3
|
+
import { a as CMS_FORM_SUBMIT_PATH } from "../../HttpPaths-c9nLZ9H2.js";
|
|
4
|
+
import { Result, Schema } from "effect";
|
|
5
|
+
import { computed, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, watch } from "vue";
|
|
6
|
+
|
|
7
|
+
//#region src/runtime/forms/useCmsForm.ts
|
|
8
|
+
/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */
|
|
9
|
+
function useCmsForm(input, options = {}) {
|
|
10
|
+
const definition = computed(() => toValue(input));
|
|
11
|
+
const steps = computed(() => definition.value.steps);
|
|
12
|
+
const fields = computed(() => steps.value.flatMap((step) => step.fields));
|
|
13
|
+
const values = ref({});
|
|
14
|
+
const errors = shallowRef({});
|
|
15
|
+
const stepIndex = ref(0);
|
|
16
|
+
const currentStep = computed(() => steps.value[stepIndex.value]);
|
|
17
|
+
const isFirstStep = computed(() => stepIndex.value === 0);
|
|
18
|
+
const isLastStep = computed(() => stepIndex.value === steps.value.length - 1);
|
|
19
|
+
const isSubmitting = ref(false);
|
|
20
|
+
const isSuccess = ref(false);
|
|
21
|
+
const isPreview = computed(() => definition.value.preview);
|
|
22
|
+
const error = shallowRef();
|
|
23
|
+
let controller;
|
|
24
|
+
let generation = 0;
|
|
25
|
+
let previousFields = /* @__PURE__ */ new Map();
|
|
26
|
+
const stop = watch(definition, (next, before) => {
|
|
27
|
+
generation++;
|
|
28
|
+
controller?.abort();
|
|
29
|
+
isSubmitting.value = false;
|
|
30
|
+
const sameForm = before?.documentId === next.documentId && JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) && before.name === next.name;
|
|
31
|
+
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 : ""]));
|
|
32
|
+
previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]));
|
|
33
|
+
stepIndex.value = Math.max(0, next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id));
|
|
34
|
+
errors.value = {};
|
|
35
|
+
error.value = void 0;
|
|
36
|
+
isSuccess.value = false;
|
|
37
|
+
}, {
|
|
38
|
+
immediate: true,
|
|
39
|
+
deep: true,
|
|
40
|
+
flush: "sync"
|
|
41
|
+
});
|
|
42
|
+
function validate() {
|
|
43
|
+
errors.value = validateFormValues(fields.value, values.value);
|
|
44
|
+
return Object.keys(errors.value).length === 0;
|
|
45
|
+
}
|
|
46
|
+
function next() {
|
|
47
|
+
if (isSubmitting.value || isLastStep.value) return false;
|
|
48
|
+
const stepFields = currentStep.value?.fields ?? [];
|
|
49
|
+
const issues = validateFormValues(stepFields, values.value);
|
|
50
|
+
errors.value = {
|
|
51
|
+
...Object.fromEntries(Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id))),
|
|
52
|
+
...issues
|
|
53
|
+
};
|
|
54
|
+
if (Object.keys(issues).length) return false;
|
|
55
|
+
stepIndex.value++;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
function previous() {
|
|
59
|
+
if (!isSubmitting.value && !isFirstStep.value) stepIndex.value--;
|
|
60
|
+
}
|
|
61
|
+
function reset() {
|
|
62
|
+
generation++;
|
|
63
|
+
controller?.abort();
|
|
64
|
+
isSubmitting.value = false;
|
|
65
|
+
values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]));
|
|
66
|
+
errors.value = {};
|
|
67
|
+
error.value = void 0;
|
|
68
|
+
isSuccess.value = false;
|
|
69
|
+
stepIndex.value = 0;
|
|
70
|
+
}
|
|
71
|
+
async function submit() {
|
|
72
|
+
if (isSubmitting.value || isSuccess.value) return false;
|
|
73
|
+
error.value = void 0;
|
|
74
|
+
if (!validate()) {
|
|
75
|
+
stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (isPreview.value) {
|
|
79
|
+
isSuccess.value = true;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
const currentGeneration = ++generation;
|
|
83
|
+
controller = new AbortController();
|
|
84
|
+
isSubmitting.value = true;
|
|
85
|
+
try {
|
|
86
|
+
const { documentId, nodePath, revision } = definition.value;
|
|
87
|
+
const result = await (options.submit ?? send)({
|
|
88
|
+
documentId,
|
|
89
|
+
nodePath,
|
|
90
|
+
revision,
|
|
91
|
+
values: { ...values.value }
|
|
92
|
+
}, controller.signal);
|
|
93
|
+
if (generation !== currentGeneration) return false;
|
|
94
|
+
errors.value = { ...result.errors };
|
|
95
|
+
isSuccess.value = result.status === "accepted";
|
|
96
|
+
if (result.status === "invalid") stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
|
|
97
|
+
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.";
|
|
98
|
+
return isSuccess.value;
|
|
99
|
+
} catch {
|
|
100
|
+
if (generation === currentGeneration) error.value = "Submission failed. Please try again.";
|
|
101
|
+
return false;
|
|
102
|
+
} finally {
|
|
103
|
+
if (generation === currentGeneration) isSubmitting.value = false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (getCurrentScope()) onScopeDispose(() => {
|
|
107
|
+
generation++;
|
|
108
|
+
controller?.abort();
|
|
109
|
+
stop();
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
fields,
|
|
113
|
+
steps,
|
|
114
|
+
values,
|
|
115
|
+
errors: readonly(errors),
|
|
116
|
+
currentStep,
|
|
117
|
+
stepIndex: readonly(stepIndex),
|
|
118
|
+
isFirstStep,
|
|
119
|
+
isLastStep,
|
|
120
|
+
isSubmitting: readonly(isSubmitting),
|
|
121
|
+
isSuccess: readonly(isSuccess),
|
|
122
|
+
isPreview,
|
|
123
|
+
error: readonly(error),
|
|
124
|
+
next,
|
|
125
|
+
previous,
|
|
126
|
+
validate,
|
|
127
|
+
submit,
|
|
128
|
+
reset
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function emptyFormValue(field) {
|
|
132
|
+
if (field.type === "checkbox") return false;
|
|
133
|
+
if (field.type === "number") return null;
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
async function send(submission, signal) {
|
|
137
|
+
const response = await fetch(CMS_FORM_SUBMIT_PATH, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "content-type": "application/json" },
|
|
140
|
+
body: JSON.stringify(submission),
|
|
141
|
+
signal
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) throw new Error("Submission failed.");
|
|
144
|
+
return Result.getOrThrow(Schema.decodeUnknownResult(FormResult)(await response.json()));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
//#endregion
|
|
148
|
+
export { useCmsForm };
|
|
149
|
+
//# sourceMappingURL=useCmsForm.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/runtime/i18n/translator.ts
|
|
2
|
+
function localeFromPath(configuration, path) {
|
|
3
|
+
const segment = path.split("/")[1] ?? "";
|
|
4
|
+
return Object.hasOwn(configuration.locales, segment) ? segment : configuration.defaultLocale;
|
|
5
|
+
}
|
|
6
|
+
function translate(configuration, locale, key, parameters = {}, missing) {
|
|
7
|
+
function lookup(code) {
|
|
8
|
+
const messages = Object.hasOwn(configuration.locales, code) ? configuration.locales[code]?.messages : void 0;
|
|
9
|
+
return messages && Object.hasOwn(messages, key) ? messages[key] : void 0;
|
|
10
|
+
}
|
|
11
|
+
let message = lookup(locale);
|
|
12
|
+
if (message === void 0) {
|
|
13
|
+
missing?.(key, locale);
|
|
14
|
+
message = configuration.fallbackLocale === null ? void 0 : lookup(configuration.fallbackLocale);
|
|
15
|
+
}
|
|
16
|
+
if (message === void 0) return key;
|
|
17
|
+
return message.replace(/\{([\w]+)\}/gu, (placeholder, name) => Object.hasOwn(parameters, name) ? String(parameters[name]) : placeholder);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { localeFromPath, translate };
|
|
22
|
+
//# sourceMappingURL=translator.js.map
|
|
@@ -0,0 +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 : configuration.defaultLocale\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,MAAM,UAAU,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM;CAEtC,OAAO,OAAO,OAAO,cAAc,SAAS,OAAO,IAAI,UAAU,cAAc;AACjF;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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { r as CmsMessageKey } from "../../I18n-DZK4CkJF.js";
|
|
2
|
+
//#region src/runtime/i18n/useCmsI18n.d.ts
|
|
3
|
+
/** 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
|
+
t: (key: CmsMessageKey, parameters?: Readonly<Record<string, string | number>>) => string;
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
//# sourceMappingURL=useCmsI18n.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { localeFromPath, translate } from "./translator.js";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { useRoute } from "nuxt/app";
|
|
4
|
+
import configuration from "#cms/i18n";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/i18n/useCmsI18n.ts
|
|
7
|
+
/** URL-owned locale is reactive and isolated to the current Nuxt application/request. */
|
|
8
|
+
function useCmsI18n() {
|
|
9
|
+
const route = useRoute();
|
|
10
|
+
const locale = computed(() => localeFromPath(configuration, route.path));
|
|
11
|
+
const warned = /* @__PURE__ */ new Set();
|
|
12
|
+
function missing(key, code) {
|
|
13
|
+
const id = `${code}:${key}`;
|
|
14
|
+
if (!import.meta.dev || warned.has(id)) return;
|
|
15
|
+
warned.add(id);
|
|
16
|
+
console.warn(`[cms i18n] Missing message "${key}" for locale "${code}".`);
|
|
17
|
+
}
|
|
18
|
+
function t(key, parameters) {
|
|
19
|
+
return translate(configuration, locale.value, key, parameters, missing);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
locale,
|
|
23
|
+
t
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { useCmsI18n };
|
|
29
|
+
//# sourceMappingURL=useCmsI18n.js.map
|
|
@@ -0,0 +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 { localeFromPath, translate } 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 return { locale, t }\n}\n"],"mappings":";;;;;;;AAOA,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,OAAO;EAAE;EAAQ;CAAE;AACrB"}
|
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-DgF2M1gL.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,
|
|
7
|
+
function createInstallationPlugin(authored, authoring, initialSources) {
|
|
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,
|
|
10
|
+
const configuration = resolveCmsInstallation(authored, authoring, initialSources);
|
|
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 { DocumentImportSource } from '@internal/protocol/Documents'\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 { DocumentImportSource } from '@internal/protocol/Documents'\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(\n authored: CmsConfiguration,\n authoring: AuthoringCatalog,\n initialSources: ReadonlyArray<DocumentImportSource>,\n) {\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, initialSources)\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":";;;;;;AAeA,SAAgB,yBACd,UACA,WACA,gBACA;CACA,OAAO,mBAAmB,UAAU;EAClC,IAAI,MAAM,iBAAiB,MAAM,IAAI,MAAM,wDAAwD;EACnG,MAAM,gBAAgB,uBAAuB,UAAU,WAAW,cAAc;EAChF,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"}
|
|
@@ -2,7 +2,6 @@ import { Predicate, Schema } from "effect";
|
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/preview/comark-document.ts
|
|
4
4
|
const isJsonObject = Schema.is(Schema.JsonObject);
|
|
5
|
-
/** Adapts the immutable wire model to the mutable tree owned by the Nuxt Comark renderer. */
|
|
6
5
|
function toPreviewRenderDocument(document) {
|
|
7
6
|
return {
|
|
8
7
|
frontmatter: mutableJsonObject(document.frontmatter),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comark-document.js","names":[],"sources":["../../../../../src/runtime/preview/comark-document.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { MarkdownDocument, Node } from 'comark'\nimport { Predicate, Schema } from 'effect'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\
|
|
1
|
+
{"version":3,"file":"comark-document.js","names":[],"sources":["../../../../../src/runtime/preview/comark-document.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { MarkdownDocument, Node } from 'comark'\nimport { Predicate, Schema } from 'effect'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\nexport function toPreviewRenderDocument(document: CmsMarkdownDocument): MarkdownDocument {\n return {\n frontmatter: mutableJsonObject(document.frontmatter),\n meta: mutableJsonObject(document.meta),\n nodes: document.nodes.map(toRenderNode),\n }\n}\n\nfunction toRenderNode(node: MarkdownNode): Node {\n if (Predicate.isString(node)) return node\n\n if (node[0] === null) return [null, mutableJsonObject(node[1]), node[2]]\n const [tag, attributes, ...children] = node\n\n return [tag, mutableJsonObject(attributes), ...children.map(toRenderNode)]\n}\n\nfunction mutableJsonObject(value: Schema.JsonObject): Record<string, Schema.Json> {\n return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, mutableJson(child)]))\n}\n\nfunction mutableJson(value: Schema.Json): Schema.Json {\n if (Array.isArray(value)) return value.map(mutableJson)\n\n if (isJsonObject(value)) return mutableJsonObject(value)\n\n return value\n}\n"],"mappings":";;;AAIA,MAAM,eAAe,OAAO,GAAG,OAAO,UAAU;AAEhD,SAAgB,wBAAwB,UAAiD;CACvF,OAAO;EACL,aAAa,kBAAkB,SAAS,WAAW;EACnD,MAAM,kBAAkB,SAAS,IAAI;EACrC,OAAO,SAAS,MAAM,IAAI,YAAY;CACxC;AACF;AAEA,SAAS,aAAa,MAA0B;CAC9C,IAAI,UAAU,SAAS,IAAI,GAAG,OAAO;CAErC,IAAI,KAAK,OAAO,MAAM,OAAO;EAAC;EAAM,kBAAkB,KAAK,EAAE;EAAG,KAAK;CAAE;CACvE,MAAM,CAAC,KAAK,YAAY,GAAG,YAAY;CAEvC,OAAO;EAAC;EAAK,kBAAkB,UAAU;EAAG,GAAG,SAAS,IAAI,YAAY;CAAC;AAC3E;AAEA,SAAS,kBAAkB,OAAuD;CAChF,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC;AAClG;AAEA,SAAS,YAAY,OAAiC;CACpD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,WAAW;CAEtD,IAAI,aAAa,KAAK,GAAG,OAAO,kBAAkB,KAAK;CAEvD,OAAO;AACT"}
|