@phtngyn/cms 0.1.0-beta.5 → 0.2.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +114 -41
  3. package/package.json +13 -1
  4. package/src/ApplicationTypes.d.ts +84 -0
  5. package/src/ApplicationTypes.js +1 -0
  6. package/src/{Configuration-CDMYfTre.js → Configuration-BU-UyGoH.js} +4 -4
  7. package/src/{Configuration-CDMYfTre.js.map → Configuration-BU-UyGoH.js.map} +1 -1
  8. package/src/Configuration.d.ts +43 -21
  9. package/src/Configuration.js.map +1 -1
  10. package/src/Content.d.ts +67 -0
  11. package/src/Content.js +291 -0
  12. package/src/Content.js.map +1 -0
  13. package/src/{ContentTransfer-C3Av9sWz.js → ContentTransfer-BhF9G56s.js} +8 -4
  14. package/src/ContentTransfer-BhF9G56s.js.map +1 -0
  15. package/src/ContentTransfer-CRQet3QJ.d.ts +48 -0
  16. package/src/{DocumentEngine-J7g-emdf.js → DocumentEngine-ClhFXW9M.js} +4 -4
  17. package/src/{DocumentEngine-J7g-emdf.js.map → DocumentEngine-ClhFXW9M.js.map} +1 -1
  18. package/src/DocumentModel.d.ts +14 -2
  19. package/src/DocumentModel.js +32 -4
  20. package/src/DocumentModel.js.map +1 -1
  21. package/src/{Forms-CfcI3tPU.js → Forms-BbkE7QfC.js} +47 -16
  22. package/src/Forms-BbkE7QfC.js.map +1 -0
  23. package/src/{Forms-Dj6NuW66.js → Forms-DoB56hfe.js} +24 -7
  24. package/src/Forms-DoB56hfe.js.map +1 -0
  25. package/src/{Forms-BsJMev5_.d.ts → Forms-R0HoTR-o.d.ts} +31 -13
  26. package/src/Forms.d.ts +23 -11
  27. package/src/Forms.js.map +1 -1
  28. package/src/I18n-zbqpWxki.d.ts +29 -0
  29. package/src/I18n.d.ts +2 -20
  30. package/src/Module.js +18 -7
  31. package/src/Module.js.map +1 -1
  32. package/src/{S3MediaObjects-CpPSzJto.js → S3MediaObjects-D5Ns4FM6.js} +61 -40
  33. package/src/S3MediaObjects-D5Ns4FM6.js.map +1 -0
  34. package/src/cli/content.js +63 -221
  35. package/src/cli/content.js.map +1 -1
  36. package/src/cli.js +120 -5
  37. package/src/cli.js.map +1 -1
  38. package/src/{connection-CBAy2qGy.js → connection-D5S9Iph-.js} +2 -2
  39. package/src/{connection-CBAy2qGy.js.map → connection-D5S9Iph-.js.map} +1 -1
  40. package/src/dev-lifecycle-CZ7iCzG9.js +515 -0
  41. package/src/dev-lifecycle-CZ7iCzG9.js.map +1 -0
  42. package/src/{installation-CNfIriVm.js → installation-BNuoRDOz.js} +601 -468
  43. package/src/installation-BNuoRDOz.js.map +1 -0
  44. package/src/internal/application-types.js +43 -0
  45. package/src/internal/application-types.js.map +1 -0
  46. package/src/internal/authoring-catalog.js +9 -4
  47. package/src/internal/authoring-catalog.js.map +1 -1
  48. package/src/internal/authoring-metadata.js +1 -1
  49. package/src/internal/configuration.js +149 -46
  50. package/src/internal/configuration.js.map +1 -1
  51. package/src/internal/dev-lifecycle.js +3 -0
  52. package/src/internal/diagnostics.js +47 -0
  53. package/src/internal/diagnostics.js.map +1 -0
  54. package/src/internal/document-model.js +2 -2
  55. package/src/internal/document-model.js.map +1 -1
  56. package/src/internal/form-capabilities.js +1 -1
  57. package/src/internal/i18n.js +27 -1
  58. package/src/internal/i18n.js.map +1 -1
  59. package/src/{location-BTqdfIzX.js → location-CPX7oj0o.js} +2 -2
  60. package/src/{location-BTqdfIzX.js.map → location-CPX7oj0o.js.map} +1 -1
  61. package/src/{models-B4IoTmp7.js → models-C9kF9JlQ.js} +2 -2
  62. package/src/{models-B4IoTmp7.js.map → models-C9kF9JlQ.js.map} +1 -1
  63. package/src/{models-Bah5B3bT.js → models-ChRxBChy.js} +9 -2
  64. package/src/models-ChRxBChy.js.map +1 -0
  65. package/src/runtime/delivery/context.js +1 -1
  66. package/src/runtime/delivery/plugin.js +28 -5
  67. package/src/runtime/delivery/plugin.js.map +1 -1
  68. package/src/runtime/delivery/preview.d.ts +1 -1
  69. package/src/runtime/delivery/types.d.ts +2 -85
  70. package/src/runtime/delivery/useCmsDocumentSeo.d.ts +8 -1
  71. package/src/runtime/delivery/useCmsDocumentSeo.js +19 -7
  72. package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
  73. package/src/runtime/delivery/useDocument.d.ts +2 -2
  74. package/src/runtime/delivery/useDocument.js.map +1 -1
  75. package/src/runtime/delivery/useDocumentQuery.d.ts +3 -3
  76. package/src/runtime/delivery/useDocumentQuery.js.map +1 -1
  77. package/src/runtime/forms/document.js +1 -1
  78. package/src/runtime/forms/useCmsForm.js +89 -45
  79. package/src/runtime/forms/useCmsForm.js.map +1 -1
  80. package/src/runtime/i18n/useCmsI18n.d.ts +9 -7
  81. package/src/runtime/i18n/useCmsI18n.js +5 -4
  82. package/src/runtime/i18n/useCmsI18n.js.map +1 -1
  83. package/src/runtime/installation.js +2 -2
  84. package/src/runtime/plugin.js +12 -4
  85. package/src/runtime/plugin.js.map +1 -1
  86. package/src/runtime/preview/connection.js +1 -1
  87. package/src/runtime/preview/controller.js +2 -2
  88. package/src/runtime/preview/plugin.client.js +3 -3
  89. package/src/runtime/preview/store.js +1 -1
  90. package/src/runtime/sitemap.js +1 -1
  91. package/src/scalars-CA6kyipS.d.ts +7 -0
  92. package/src/{store-b2CSXgMt.js → store-B49J21NA.js} +3 -3
  93. package/src/{store-b2CSXgMt.js.map → store-B49J21NA.js.map} +1 -1
  94. package/src/types-DutFRtaG.d.ts +90 -0
  95. package/studio/{CreateDocumentDialog-GGey1uBc.js → CreateDocumentDialog-DJ8c0WZb.js} +3 -3
  96. package/studio/{documentPlanning-DRErYmBU.js → documentPlanning-CDb31mnl.js} +5935 -5869
  97. package/studio/host.css +1 -1
  98. package/studio/host.js +7608 -7250
  99. package/src/ContentTransfer-C3Av9sWz.js.map +0 -1
  100. package/src/Forms-CfcI3tPU.js.map +0 -1
  101. package/src/Forms-Dj6NuW66.js.map +0 -1
  102. package/src/S3MediaObjects-CpPSzJto.js.map +0 -1
  103. package/src/installation-CNfIriVm.js.map +0 -1
  104. package/src/models-Bah5B3bT.js.map +0 -1
@@ -1,85 +1,2 @@
1
- import { n as ResolvedSeo, t as DocumentSeo } from "../../Seo-402YumpT.js";
2
- import { DateTime } from "effect";
3
- //#region src/runtime/delivery/types.d.ts
4
- export type DeliveryJson = null | boolean | number | string | ReadonlyArray<DeliveryJson> | DeliveryJsonObject;
5
- export interface DeliveryJsonObject {
6
- readonly [key: string]: DeliveryJson;
7
- }
8
- export type DeliveryMarkdownNode = string | readonly [null, DeliveryJsonObject, string] | readonly [string, DeliveryJsonObject, ...DeliveryMarkdownNode[]];
9
- export interface DeliveryMarkdownDocument {
10
- readonly frontmatter: DeliveryJsonObject;
11
- readonly meta: DeliveryJsonObject;
12
- readonly nodes: ReadonlyArray<DeliveryMarkdownNode>;
13
- }
14
- export interface DeliveryDocument {
15
- readonly analysis: {
16
- readonly components: ReadonlyArray<string>;
17
- readonly headings: ReadonlyArray<{
18
- readonly depth: number;
19
- readonly id: string;
20
- readonly text: string;
21
- }>;
22
- readonly searchText: string;
23
- readonly summary: string;
24
- };
25
- readonly body: DeliveryMarkdownDocument;
26
- readonly collection: string;
27
- readonly data: DeliveryJsonObject;
28
- readonly description?: string;
29
- readonly draft: boolean;
30
- readonly engineFingerprint: string;
31
- readonly id: string;
32
- readonly issues: ReadonlyArray<{
33
- readonly code: string;
34
- readonly collection?: string;
35
- readonly field?: string;
36
- readonly key?: string;
37
- readonly locale?: string;
38
- readonly message: string;
39
- readonly severity: 'error' | 'warning';
40
- readonly sourcePath?: string;
41
- }>;
42
- readonly key: string;
43
- readonly locale?: string;
44
- readonly path: string;
45
- readonly resolvedSeo?: ResolvedSeo;
46
- readonly seo?: DocumentSeo;
47
- readonly source: {
48
- readonly mappings: ReadonlyArray<{
49
- readonly nodePath: ReadonlyArray<number>;
50
- readonly range: {
51
- readonly end: {
52
- readonly column: number;
53
- readonly line: number;
54
- readonly offset: number;
55
- };
56
- readonly start: {
57
- readonly column: number;
58
- readonly line: number;
59
- readonly offset: number;
60
- };
61
- };
62
- }>;
63
- readonly path: string;
64
- readonly publishedAt?: DateTime.Utc;
65
- };
66
- readonly title: string;
67
- }
68
- export interface DeliveryDocumentPage {
69
- readonly items: ReadonlyArray<DeliveryDocument>;
70
- readonly total: number;
71
- }
72
- export interface DeliveryDocumentQuerySort {
73
- readonly direction?: 'asc' | 'desc';
74
- readonly field: string;
75
- }
76
- export interface DeliveryDocumentQuery {
77
- readonly collection?: string;
78
- readonly locale?: string;
79
- readonly limit: number;
80
- readonly offset?: number;
81
- readonly sort?: DeliveryDocumentQuerySort | ReadonlyArray<DeliveryDocumentQuerySort>;
82
- readonly where?: Readonly<Record<string, boolean | number | string | null | ReadonlyArray<boolean | number | string | null>>>;
83
- }
84
- //#endregion
85
- //# sourceMappingURL=types.d.ts.map
1
+ import { a as DeliveryJson, c as DeliveryMarkdownNode, i as DeliveryDocumentQuerySort, n as DeliveryDocumentPage, o as DeliveryJsonObject, r as DeliveryDocumentQuery, s as DeliveryMarkdownDocument, t as DeliveryDocument } from "../../types-DutFRtaG.js";
2
+ export { DeliveryDocument, DeliveryDocumentPage, DeliveryDocumentQuery, DeliveryDocumentQuerySort, DeliveryJson, DeliveryJsonObject, DeliveryMarkdownDocument, DeliveryMarkdownNode };
@@ -1,5 +1,5 @@
1
1
  import { i as SiteIdentity } from "../../Seo-402YumpT.js";
2
- import { DeliveryDocument } from "./types.js";
2
+ import { t as DeliveryDocument } from "../../types-DutFRtaG.js";
3
3
  import { ComputedRef, MaybeRefOrGetter } from "vue";
4
4
  //#region src/runtime/delivery/useCmsDocumentSeo.d.ts
5
5
  type ReactiveMetadataValue = () => string | undefined;
@@ -10,6 +10,7 @@ export interface CmsSeoMetadata {
10
10
  readonly ogDescription: ReactiveMetadataValue;
11
11
  readonly ogImage: ReactiveMetadataValue;
12
12
  readonly ogImageAlt: ReactiveMetadataValue;
13
+ readonly ogLocale: ReactiveMetadataValue;
13
14
  readonly robots: ReactiveMetadataValue;
14
15
  }
15
16
  interface CmsIdentitySchemaNode {
@@ -32,6 +33,7 @@ interface CmsPageSchemaNode {
32
33
  readonly headline?: string;
33
34
  readonly datePublished?: string;
34
35
  readonly dateModified?: string;
36
+ readonly inLanguage?: string;
35
37
  }
36
38
  export type CmsSeoSchemaNode = CmsIdentitySchemaNode | CmsPageSchemaNode;
37
39
  export interface CmsDocumentSeoAdapters {
@@ -42,6 +44,10 @@ export interface CmsDocumentSeoAdapters {
42
44
  link: Array<{
43
45
  href: string;
44
46
  rel: 'canonical';
47
+ } | {
48
+ href: string;
49
+ hreflang: string;
50
+ rel: 'alternate';
45
51
  }>;
46
52
  titleTemplate: null;
47
53
  }) => void;
@@ -51,6 +57,7 @@ export interface CmsDocumentSeoAdapters {
51
57
  }>) => void;
52
58
  readonly schema: (input: ComputedRef<ReadonlyArray<CmsSeoSchemaNode>>) => void;
53
59
  readonly seoMeta: (input: CmsSeoMetadata) => void;
60
+ readonly locale: (input: ComputedRef<string | undefined>) => void;
54
61
  }
55
62
  /** Installs Nuxt's composables once before document page setup. */
56
63
  export declare function installCmsDocumentSeoAdapters(adapters: CmsDocumentSeoAdapters): void;
@@ -17,21 +17,32 @@ function useCmsDocumentSeo(document) {
17
17
  ogDescription: () => seo.value?.socialDescription,
18
18
  ogImage: () => seo.value?.socialImage?.url,
19
19
  ogImageAlt: () => seo.value?.socialImage?.alt,
20
+ ogLocale: () => current.value?.locale,
20
21
  robots: () => seo.value ? `${seo.value.index ? "index" : "noindex"}, ${seo.value.follow ? "follow" : "nofollow"}` : void 0
21
22
  });
23
+ adapters.locale(computed(() => current.value?.locale));
22
24
  adapters.head(() => ({
23
25
  ...current.value?.locale ? { htmlAttrs: { lang: current.value.locale } } : void 0,
24
- link: seo.value?.canonicalUrl ? [{
25
- href: seo.value.canonicalUrl,
26
- rel: "canonical"
27
- }] : [],
26
+ link: links(current.value, seo.value?.canonicalUrl),
28
27
  titleTemplate: null
29
28
  }));
30
29
  adapters.robots(computed(() => ({
31
30
  follow: seo.value?.follow ?? true,
32
31
  index: seo.value?.index ?? true
33
32
  })));
34
- adapters.schema(computed(() => seo.value ? schemaNodes(seo.value) : []));
33
+ adapters.schema(computed(() => seo.value ? schemaNodes(seo.value, current.value?.locale) : []));
34
+ }
35
+ function links(document, canonicalUrl) {
36
+ const canonical = canonicalUrl ? [{
37
+ href: canonicalUrl,
38
+ rel: "canonical"
39
+ }] : [];
40
+ if (!canonicalUrl || !document?.alternatives) return canonical;
41
+ return [...canonical, ...document.alternatives.map((alternative) => ({
42
+ href: new URL(alternative.path, canonicalUrl).href,
43
+ hreflang: alternative.locale,
44
+ rel: "alternate"
45
+ }))];
35
46
  }
36
47
  function installedCmsDocumentSeoAdapters() {
37
48
  if (!installedAdapters) throw new Error("The CMS document SEO adapter has not been installed.");
@@ -50,14 +61,15 @@ function resolvedSeo(document) {
50
61
  title: document.title
51
62
  };
52
63
  }
53
- function schemaNodes(seo) {
64
+ function schemaNodes(seo, locale) {
54
65
  const identity = seo.identity ? [identityNode(seo.identity)] : [];
55
66
  if (!seo.structuredData) return identity;
56
67
  const common = {
57
68
  name: seo.title,
58
69
  ...seo.description ? { description: seo.description } : void 0,
59
70
  ...seo.socialImage ? { image: seo.socialImage.url } : void 0,
60
- ...seo.canonicalUrl ? { url: seo.canonicalUrl } : void 0
71
+ ...seo.canonicalUrl ? { url: seo.canonicalUrl } : void 0,
72
+ ...locale ? { inLanguage: locale } : void 0
61
73
  };
62
74
  if (seo.structuredData.type === "Article") return [...identity, {
63
75
  "@type": "Article",
@@ -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 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
+ {"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 ogLocale: 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 readonly inLanguage?: 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' } | { href: string; hreflang: string; rel: 'alternate' }>\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 readonly locale: (input: ComputedRef<string | undefined>) => 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 ogLocale: () => current.value?.locale,\n robots: () =>\n seo.value ? `${seo.value.index ? 'index' : 'noindex'}, ${seo.value.follow ? 'follow' : 'nofollow'}` : undefined,\n })\n\n adapters.locale(computed(() => current.value?.locale))\n adapters.head(() => ({\n ...(current.value?.locale ? { htmlAttrs: { lang: current.value.locale } } : undefined),\n link: links(current.value, seo.value?.canonicalUrl),\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, current.value?.locale) : [])))\n}\n\nfunction links(document: DeliveryDocument | null, canonicalUrl?: string) {\n const canonical = canonicalUrl ? [{ href: canonicalUrl, rel: 'canonical' as const }] : []\n\n if (!canonicalUrl || !document?.alternatives) return canonical\n\n return [\n ...canonical,\n ...document.alternatives.map((alternative) => ({\n href: new URL(alternative.path, canonicalUrl).href,\n hreflang: alternative.locale,\n rel: 'alternate' as const,\n })),\n ]\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, locale?: string): 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 ...(locale ? { inLanguage: locale } : 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,6 +1,6 @@
1
- import { DeliveryDocument } from "./types.js";
1
+ import { CmsCollection, CmsCollectionName } from "../../ApplicationTypes.js";
2
2
  import { MaybeRefOrGetter } from "vue";
3
3
  //#region src/runtime/delivery/useDocument.d.ts
4
- export declare function useDocument(path: MaybeRefOrGetter<string>): import("nuxt/app").AsyncData<DeliveryDocument | null, import("nuxt/app").NuxtError<unknown> | undefined>;
4
+ export declare function useDocument<Name extends CmsCollectionName = CmsCollectionName>(path: MaybeRefOrGetter<string>): import("nuxt/app").AsyncData<CmsCollection<Name> | null, import("nuxt/app").NuxtError<unknown> | undefined>;
5
5
  //#endregion
6
6
  //# sourceMappingURL=useDocument.d.ts.map
@@ -1 +1 @@
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
+ {"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 { CmsCollection, CmsCollectionName } from '../../ApplicationTypes'\n\nexport function useDocument<Name extends CmsCollectionName = CmsCollectionName>(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<CmsCollection<Name> | null>(endpoint, {\n body,\n default: () => null,\n method: 'POST',\n })\n}\n"],"mappings":";;;;;;AAOA,SAAgB,YAAgE,MAAgC;CAC9G,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,SAAqC,UAAU;EACpD;EACA,eAAe;EACf,QAAQ;CACV,CAAC;AACH"}
@@ -1,7 +1,7 @@
1
- import { DeliveryDocumentPage, DeliveryDocumentQuery, DeliveryDocumentQuerySort } from "./types.js";
1
+ import { CmsCollectionName, CmsDocumentPage, CmsDocumentQuery, CmsDocumentQuerySort } from "../../ApplicationTypes.js";
2
2
  import { MaybeRefOrGetter } from "vue";
3
3
  //#region src/runtime/delivery/useDocumentQuery.d.ts
4
- export declare function useDocumentQuery(query: MaybeRefOrGetter<DeliveryDocumentQuery>): import("nuxt/app").AsyncData<DeliveryDocumentPage, import("nuxt/app").NuxtError<unknown> | undefined>;
4
+ export declare function useDocumentQuery<Name extends CmsCollectionName = CmsCollectionName>(query: MaybeRefOrGetter<CmsDocumentQuery<Name>>): import("nuxt/app").AsyncData<CmsDocumentPage<Name>, import("nuxt/app").NuxtError<unknown> | undefined>;
5
5
  //#endregion
6
- export type { DeliveryDocumentQuery, DeliveryDocumentQuerySort };
6
+ export type { CmsDocumentQuery, CmsDocumentQuerySort };
7
7
  //# sourceMappingURL=useDocumentQuery.d.ts.map
@@ -1 +1 @@
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"}
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 { CmsCollectionName, CmsDocumentPage, CmsDocumentQuery } from '../../ApplicationTypes'\n\nexport type { CmsDocumentQuery, CmsDocumentQuerySort } from '../../ApplicationTypes'\n\nexport function useDocumentQuery<Name extends CmsCollectionName = CmsCollectionName>(\n query: MaybeRefOrGetter<CmsDocumentQuery<Name>>,\n) {\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<CmsDocumentPage<Name>>(endpoint, {\n body,\n default: () => ({ items: [], total: 0 }),\n method: 'POST',\n })\n}\n"],"mappings":";;;;;;AASA,SAAgB,iBACd,OACA;CACA,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,SAAgC,UAAU;EAC/C;EACA,gBAAgB;GAAE,OAAO,CAAC;GAAG,OAAO;EAAE;EACtC,QAAQ;CACV,CAAC;AACH"}
@@ -1,5 +1,5 @@
1
1
  import { r as DocumentId } from "../../scalars-B2lgGUnj.js";
2
- import { t as documentForms } from "../../Forms-Dj6NuW66.js";
2
+ import { t as documentForms } from "../../Forms-DoB56hfe.js";
3
3
  import { Predicate, Result, Schema } from "effect";
4
4
 
5
5
  //#region src/runtime/forms/document.ts
@@ -1,8 +1,8 @@
1
- import { i as FormResult } from "../../Forms-CfcI3tPU.js";
2
- import { i as validateFormValues } from "../../Forms-Dj6NuW66.js";
3
1
  import { a as CMS_FORM_SUBMIT_PATH } from "../../HttpPaths-c9nLZ9H2.js";
2
+ import { o as FormResult } from "../../Forms-BbkE7QfC.js";
3
+ import { i as validateFormValues } from "../../Forms-DoB56hfe.js";
4
4
  import { Result, Schema } from "effect";
5
- import { computed, getCurrentInstance, getCurrentScope, onScopeDispose, readonly, ref, shallowRef, toValue, useId, watch } from "vue";
5
+ import { computed, getCurrentInstance, getCurrentScope, onScopeDispose, reactive, 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. */
@@ -17,23 +17,26 @@ function useCmsForm(input, options = {}) {
17
17
  const currentStep = computed(() => steps.value[stepIndex.value]);
18
18
  const isFirstStep = computed(() => stepIndex.value === 0);
19
19
  const isLastStep = computed(() => stepIndex.value === steps.value.length - 1);
20
- const isSubmitting = ref(false);
20
+ const submitting = ref(false);
21
21
  const isSuccess = ref(false);
22
22
  const isPreview = computed(() => definition.value.preview);
23
- const error = shallowRef();
23
+ const submitError = shallowRef();
24
+ const touched = ref(/* @__PURE__ */ new Set());
25
+ const controls = /* @__PURE__ */ new Map();
24
26
  let controller;
25
27
  let generation = 0;
26
28
  let previousFields = /* @__PURE__ */ new Map();
27
29
  const stop = watch(definition, (next, before) => {
28
30
  generation++;
29
31
  controller?.abort();
30
- isSubmitting.value = false;
32
+ submitting.value = false;
31
33
  const sameForm = before?.documentId === next.documentId && JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) && before.name === next.name;
32
34
  values.value = Object.fromEntries(next.steps.flatMap((step) => step.fields).map((field) => [field.id, sameForm && previousFields.get(field.id) === field.type ? values.value[field.id] ?? null : field.type === "checkbox" ? false : field.type === "number" ? null : ""]));
33
35
  previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]));
34
36
  stepIndex.value = Math.max(0, next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id));
35
37
  errors.value = {};
36
- error.value = void 0;
38
+ touched.value = /* @__PURE__ */ new Set();
39
+ submitError.value = void 0;
37
40
  isSuccess.value = false;
38
41
  }, {
39
42
  immediate: true,
@@ -41,41 +44,73 @@ function useCmsForm(input, options = {}) {
41
44
  flush: "sync"
42
45
  });
43
46
  function validate() {
47
+ touched.value = new Set(fields.value.map((field) => field.id));
44
48
  errors.value = validateFormValues(fields.value, values.value);
45
49
  return Object.keys(errors.value).length === 0;
46
50
  }
47
- function fieldState(field) {
48
- const id = `${fieldIdPrefix}-${encodeURIComponent(field.id)}`;
49
- return {
50
- field,
51
- get value() {
52
- return values.value[field.id] ?? emptyFormValue(field);
53
- },
54
- get error() {
55
- return errors.value[field.id];
56
- },
57
- helpId: `${id}-help`,
58
- errorId: `${id}-error`,
59
- get inputAttrs() {
60
- const error = errors.value[field.id];
61
- const invalid = error ? "true" : void 0;
62
- const describedBy = [field.help ? `${id}-help` : void 0, error ? `${id}-error` : void 0].filter((part) => part !== void 0).join(" ");
51
+ function control(input) {
52
+ const fieldId = Schema.is(Schema.String)(input) ? input : input.id;
53
+ const existing = controls.get(fieldId);
54
+ if (existing) return existing;
55
+ if (!fields.value.some((candidate) => candidate.id === fieldId)) throw new Error(`Unknown CMS form field ${fieldId}.`);
56
+ const current = computed(() => {
57
+ const candidate = fields.value.find((field) => field.id === fieldId);
58
+ if (!candidate) throw new Error(`CMS form field ${fieldId} no longer exists.`);
59
+ return candidate;
60
+ });
61
+ const controlId = `${fieldIdPrefix}-${encodeURIComponent(fieldId)}`;
62
+ const helpId = `${controlId}-help`;
63
+ const errorId = `${controlId}-error`;
64
+ const helpAttrs = { id: helpId };
65
+ const errorAttrs = {
66
+ id: errorId,
67
+ role: "alert"
68
+ };
69
+ const refreshError = () => {
70
+ const issue = validateFormValues([current.value], values.value)[fieldId];
71
+ const nextErrors = { ...errors.value };
72
+ if (issue) nextErrors[fieldId] = issue;
73
+ else delete nextErrors[fieldId];
74
+ errors.value = nextErrors;
75
+ };
76
+ const state = reactive({
77
+ field: current,
78
+ value: computed({
79
+ get: () => values.value[fieldId] ?? emptyFormValue(current.value),
80
+ set: (value) => {
81
+ values.value[fieldId] = normalizeFormValue(current.value, value);
82
+ if (touched.value.has(fieldId) || errors.value[fieldId]) refreshError();
83
+ }
84
+ }),
85
+ dirty: computed(() => values.value[fieldId] !== emptyFormValue(current.value)),
86
+ touched: computed(() => touched.value.has(fieldId)),
87
+ valid: computed(() => validateFormValues([current.value], values.value)[fieldId] === void 0),
88
+ error: computed(() => errors.value[fieldId]),
89
+ attrs: computed(() => {
90
+ const fieldError = errors.value[fieldId];
91
+ const describedBy = [current.value.help ? helpId : void 0, fieldError ? errorId : void 0].filter((part) => part !== void 0).join(" ");
63
92
  return {
64
- id,
65
- name: field.id,
66
- required: field.required === true,
67
- "aria-invalid": invalid,
93
+ id: controlId,
94
+ name: fieldId,
95
+ required: current.value.required === true,
96
+ "aria-invalid": fieldError ? "true" : void 0,
68
97
  "aria-describedby": describedBy || void 0
69
98
  };
70
- },
71
- setValue: (value) => {
72
- values.value[field.id] = normalizeFormValue(field, value);
99
+ }),
100
+ helpAttrs,
101
+ errorAttrs,
102
+ touch: () => {
103
+ touched.value = /* @__PURE__ */ new Set([...touched.value, fieldId]);
104
+ refreshError();
73
105
  }
74
- };
106
+ });
107
+ controls.set(fieldId, state);
108
+ return state;
75
109
  }
76
110
  function next() {
77
- if (isSubmitting.value || isLastStep.value) return false;
111
+ if (submitting.value || isLastStep.value) return false;
78
112
  const stepFields = currentStep.value?.fields ?? [];
113
+ touched.value = /* @__PURE__ */ new Set([...touched.value, ...stepFields.map((field) => field.id)]);
79
114
  const issues = validateFormValues(stepFields, values.value);
80
115
  errors.value = {
81
116
  ...Object.fromEntries(Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id))),
@@ -86,21 +121,22 @@ function useCmsForm(input, options = {}) {
86
121
  return true;
87
122
  }
88
123
  function previous() {
89
- if (!isSubmitting.value && !isFirstStep.value) stepIndex.value--;
124
+ if (!submitting.value && !isFirstStep.value) stepIndex.value--;
90
125
  }
91
126
  function reset() {
92
127
  generation++;
93
128
  controller?.abort();
94
- isSubmitting.value = false;
129
+ submitting.value = false;
95
130
  values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]));
96
131
  errors.value = {};
97
- error.value = void 0;
132
+ touched.value = /* @__PURE__ */ new Set();
133
+ submitError.value = void 0;
98
134
  isSuccess.value = false;
99
135
  stepIndex.value = 0;
100
136
  }
101
137
  async function submit() {
102
- if (isSubmitting.value || isSuccess.value) return false;
103
- error.value = void 0;
138
+ if (submitting.value || isSuccess.value) return false;
139
+ submitError.value = void 0;
104
140
  if (!validate()) {
105
141
  stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
106
142
  return false;
@@ -111,7 +147,7 @@ function useCmsForm(input, options = {}) {
111
147
  }
112
148
  const currentGeneration = ++generation;
113
149
  controller = new AbortController();
114
- isSubmitting.value = true;
150
+ submitting.value = true;
115
151
  try {
116
152
  const { documentId, nodePath, revision } = definition.value;
117
153
  const result = await (options.submit ?? send)({
@@ -121,16 +157,16 @@ function useCmsForm(input, options = {}) {
121
157
  values: { ...values.value }
122
158
  }, controller.signal);
123
159
  if (generation !== currentGeneration) return false;
124
- errors.value = { ...result.errors };
160
+ errors.value = result.status === "invalid" ? { ...result.errors } : {};
125
161
  isSuccess.value = result.status === "accepted";
126
162
  if (result.status === "invalid") stepIndex.value = Math.max(0, steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])));
127
- if (result.status !== "accepted" && result.status !== "invalid") error.value = result.status === "stale" ? "This form has changed. Reload the page before submitting." : "Submission failed. Please try again.";
163
+ if (result.status !== "accepted" && result.status !== "invalid") submitError.value = result.status === "stale" ? "This form has changed. Reload the page before submitting." : "Submission failed. Please try again.";
128
164
  return isSuccess.value;
129
165
  } catch {
130
- if (generation === currentGeneration) error.value = "Submission failed. Please try again.";
166
+ if (generation === currentGeneration) submitError.value = "Submission failed. Please try again.";
131
167
  return false;
132
168
  } finally {
133
- if (generation === currentGeneration) isSubmitting.value = false;
169
+ if (generation === currentGeneration) submitting.value = false;
134
170
  }
135
171
  }
136
172
  if (getCurrentScope()) onScopeDispose(() => {
@@ -138,6 +174,10 @@ function useCmsForm(input, options = {}) {
138
174
  controller?.abort();
139
175
  stop();
140
176
  });
177
+ const visibleControls = computed(() => currentStep.value?.fields.map((entry) => control(entry)) ?? []);
178
+ const invalidControls = computed(() => fields.value.map((entry) => control(entry)).filter((entry) => !entry.valid));
179
+ const firstInvalidControlId = computed(() => invalidControls.value[0]?.attrs.id);
180
+ const canSubmit = computed(() => !submitting.value && !isSuccess.value && invalidControls.value.length === 0);
141
181
  return {
142
182
  fields,
143
183
  steps,
@@ -147,11 +187,15 @@ function useCmsForm(input, options = {}) {
147
187
  stepIndex: readonly(stepIndex),
148
188
  isFirstStep,
149
189
  isLastStep,
150
- isSubmitting: readonly(isSubmitting),
190
+ submitting: readonly(submitting),
151
191
  isSuccess: readonly(isSuccess),
152
192
  isPreview,
153
- error: readonly(error),
154
- fieldState,
193
+ submitError: readonly(submitError),
194
+ canSubmit,
195
+ visibleControls,
196
+ invalidControls,
197
+ firstInvalidControlId,
198
+ control,
155
199
  next,
156
200
  previous,
157
201
  validate,
@@ -1 +1 @@
1
- {"version":3,"file":"useCmsForm.js","names":[],"sources":["../../../../../src/runtime/forms/useCmsForm.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ComputedRef } from 'vue'\nimport type { FormDefinition, FormField, FormStep, FormSubmission, FormValues } from '@internal/protocol/Forms'\nimport { FormResult } from '@internal/protocol/Forms'\nimport { validateFormValues } from '@internal/document/Forms'\nimport { Result, Schema } from 'effect'\nimport {\n computed,\n getCurrentInstance,\n getCurrentScope,\n onScopeDispose,\n readonly,\n ref,\n shallowRef,\n toValue,\n useId,\n watch,\n} from 'vue'\nimport { CMS_FORM_SUBMIT_PATH } from '@internal/protocol/HttpPaths'\n\nexport interface UseCmsFormOptions {\n /** Replace the HTTP transport, retaining validation and submission state. */\n readonly submit?: (submission: FormSubmission, signal: AbortSignal) => Promise<FormResult>\n}\n\nexport interface CmsFormFieldState {\n readonly field: FormField\n readonly value: FormValues[string]\n readonly error: string | undefined\n readonly helpId: string\n readonly errorId: string\n readonly inputAttrs: {\n readonly id: string\n readonly name: string\n readonly required: boolean\n readonly 'aria-invalid': 'true' | undefined\n readonly 'aria-describedby': string | undefined\n }\n readonly setValue: (value: FormValues[string] | undefined) => void\n}\n\nexport interface UseCmsFormReturn {\n readonly fields: ComputedRef<ReadonlyArray<FormField>>\n readonly steps: ComputedRef<ReadonlyArray<FormStep>>\n readonly values: Ref<Record<string, FormValues[string]>>\n readonly errors: Readonly<Ref<Readonly<Record<string, string>>>>\n readonly currentStep: ComputedRef<FormStep | undefined>\n readonly stepIndex: Readonly<Ref<number>>\n readonly isFirstStep: ComputedRef<boolean>\n readonly isLastStep: ComputedRef<boolean>\n readonly isSubmitting: Readonly<Ref<boolean>>\n readonly isSuccess: Readonly<Ref<boolean>>\n readonly isPreview: ComputedRef<boolean>\n readonly error: Readonly<Ref<string | undefined>>\n readonly fieldState: (field: FormField) => CmsFormFieldState\n readonly next: () => boolean\n readonly previous: () => void\n readonly validate: () => boolean\n readonly submit: () => Promise<boolean>\n readonly reset: () => void\n}\n\n/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */\nexport function useCmsForm(input: MaybeRefOrGetter<FormDefinition>, options: UseCmsFormOptions = {}): UseCmsFormReturn {\n const fieldIdPrefix = getCurrentInstance() ? useId() : 'cms-form'\n const definition = computed(() => toValue(input))\n const steps = computed(() => definition.value.steps)\n const fields = computed(() => steps.value.flatMap((step) => step.fields))\n const values = ref<Record<string, FormValues[string]>>({})\n const errors = shallowRef<Record<string, string>>({})\n const stepIndex = ref(0)\n const currentStep = computed(() => steps.value[stepIndex.value])\n const isFirstStep = computed(() => stepIndex.value === 0)\n const isLastStep = computed(() => stepIndex.value === steps.value.length - 1)\n const isSubmitting = ref(false)\n const isSuccess = ref(false)\n const isPreview = computed(() => definition.value.preview)\n const error = shallowRef<string>()\n let controller: AbortController | undefined\n let generation = 0\n let previousFields = new Map<string, string>()\n\n const stop = watch(\n definition,\n (next, before) => {\n generation++\n controller?.abort()\n isSubmitting.value = false\n\n const sameForm =\n before?.documentId === next.documentId &&\n JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) &&\n before.name === next.name\n\n values.value = Object.fromEntries(\n next.steps\n .flatMap((step) => step.fields)\n .map((field) => [\n field.id,\n sameForm && previousFields.get(field.id) === field.type\n ? (values.value[field.id] ?? null)\n : field.type === 'checkbox'\n ? false\n : field.type === 'number'\n ? null\n : '',\n ]),\n )\n previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]))\n stepIndex.value = Math.max(\n 0,\n next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id),\n )\n errors.value = {}\n error.value = undefined\n isSuccess.value = false\n },\n { immediate: true, deep: true, flush: 'sync' },\n )\n\n function validate(): boolean {\n errors.value = validateFormValues(fields.value, values.value)\n\n return Object.keys(errors.value).length === 0\n }\n\n function fieldState(field: FormField): CmsFormFieldState {\n const id = `${fieldIdPrefix}-${encodeURIComponent(field.id)}`\n\n return {\n field,\n get value() {\n return values.value[field.id] ?? emptyFormValue(field)\n },\n get error() {\n return errors.value[field.id]\n },\n helpId: `${id}-help`,\n errorId: `${id}-error`,\n get inputAttrs() {\n const error = errors.value[field.id]\n const invalid: 'true' | undefined = error ? 'true' : undefined\n\n const describedBy = [field.help ? `${id}-help` : undefined, error ? `${id}-error` : undefined]\n .filter((part) => part !== undefined)\n .join(' ')\n\n return {\n id,\n name: field.id,\n required: field.required === true,\n 'aria-invalid': invalid,\n 'aria-describedby': describedBy || undefined,\n }\n },\n setValue: (value) => {\n values.value[field.id] = normalizeFormValue(field, value)\n },\n }\n }\n\n function next(): boolean {\n if (isSubmitting.value || isLastStep.value) return false\n const stepFields = currentStep.value?.fields ?? []\n const issues = validateFormValues(stepFields, values.value)\n errors.value = {\n ...Object.fromEntries(\n Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id)),\n ),\n ...issues,\n }\n\n if (Object.keys(issues).length) return false\n stepIndex.value++\n\n return true\n }\n\n function previous(): void {\n if (!isSubmitting.value && !isFirstStep.value) stepIndex.value--\n }\n\n function reset(): void {\n generation++\n controller?.abort()\n isSubmitting.value = false\n values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]))\n errors.value = {}\n error.value = undefined\n isSuccess.value = false\n stepIndex.value = 0\n }\n\n async function submit(): Promise<boolean> {\n if (isSubmitting.value || isSuccess.value) return false\n error.value = undefined\n\n if (!validate()) {\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n return false\n }\n\n if (isPreview.value) {\n isSuccess.value = true\n\n return true\n }\n\n const currentGeneration = ++generation\n controller = new AbortController()\n isSubmitting.value = true\n\n try {\n const { documentId, nodePath, revision } = definition.value\n\n const result = await (options.submit ?? send)(\n { documentId, nodePath, revision, values: { ...values.value } },\n controller.signal,\n )\n\n if (generation !== currentGeneration) return false\n errors.value = { ...result.errors }\n isSuccess.value = result.status === 'accepted'\n\n if (result.status === 'invalid')\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n if (result.status !== 'accepted' && result.status !== 'invalid')\n error.value =\n result.status === 'stale'\n ? 'This form has changed. Reload the page before submitting.'\n : 'Submission failed. Please try again.'\n\n return isSuccess.value\n } catch {\n if (generation === currentGeneration) error.value = 'Submission failed. Please try again.'\n\n return false\n } finally {\n if (generation === currentGeneration) isSubmitting.value = false\n }\n }\n\n if (getCurrentScope())\n onScopeDispose(() => {\n generation++\n controller?.abort()\n stop()\n })\n\n return {\n fields,\n steps,\n values,\n errors: readonly(errors),\n currentStep,\n stepIndex: readonly(stepIndex),\n isFirstStep,\n isLastStep,\n isSubmitting: readonly(isSubmitting),\n isSuccess: readonly(isSuccess),\n isPreview,\n error: readonly(error),\n fieldState,\n next,\n previous,\n validate,\n submit,\n reset,\n }\n}\n\nfunction normalizeFormValue(field: FormField, input: FormValues[string] | undefined): FormValues[string] {\n if (field.type === 'checkbox') return input === true\n\n if (field.type === 'number') {\n if (input === '' || input == null) return null\n const value = Schema.is(Schema.Finite)(input) || Schema.is(Schema.String)(input) ? Number(input) : Number.NaN\n\n if (Number.isFinite(value)) return value\n\n return Schema.is(Schema.String)(input) ? input : null\n }\n\n return Schema.is(Schema.String)(input) ? input : ''\n}\n\nfunction emptyFormValue(field: FormField): FormValues[string] {\n if (field.type === 'checkbox') return false\n\n if (field.type === 'number') return null\n\n return ''\n}\n\nasync function send(submission: FormSubmission, signal: AbortSignal): Promise<FormResult> {\n const response = await fetch(CMS_FORM_SUBMIT_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(submission),\n signal,\n })\n\n if (!response.ok) throw new Error('Submission failed.')\n\n return Result.getOrThrow(Schema.decodeUnknownResult(FormResult)(await response.json()))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useCmsForm.js","names":[],"sources":["../../../../../src/runtime/forms/useCmsForm.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ComputedRef } 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 reactive,\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 CmsFormControl {\n readonly field: FormField\n value: FormValues[string]\n readonly dirty: boolean\n readonly touched: boolean\n readonly valid: boolean\n readonly error: string | undefined\n readonly attrs: {\n readonly id: string\n readonly name: string\n readonly required: boolean\n readonly 'aria-invalid': 'true' | undefined\n readonly 'aria-describedby': string | undefined\n }\n readonly helpAttrs: { readonly id: string }\n readonly errorAttrs: { readonly id: string; readonly role: 'alert' }\n readonly touch: () => void\n}\n\nexport interface UseCmsFormReturn {\n readonly fields: ComputedRef<ReadonlyArray<FormField>>\n readonly steps: ComputedRef<ReadonlyArray<FormStep>>\n readonly values: Ref<Record<string, FormValues[string]>>\n readonly errors: Readonly<Ref<Readonly<Record<string, string>>>>\n readonly currentStep: ComputedRef<FormStep | undefined>\n readonly stepIndex: Readonly<Ref<number>>\n readonly isFirstStep: ComputedRef<boolean>\n readonly isLastStep: ComputedRef<boolean>\n readonly submitting: Readonly<Ref<boolean>>\n readonly isSuccess: Readonly<Ref<boolean>>\n readonly isPreview: ComputedRef<boolean>\n readonly submitError: Readonly<Ref<string | undefined>>\n readonly canSubmit: ComputedRef<boolean>\n readonly visibleControls: ComputedRef<ReadonlyArray<CmsFormControl>>\n readonly invalidControls: ComputedRef<ReadonlyArray<CmsFormControl>>\n readonly firstInvalidControlId: ComputedRef<string | undefined>\n readonly control: (field: string | FormField) => CmsFormControl\n readonly next: () => boolean\n readonly previous: () => void\n readonly validate: () => boolean\n readonly submit: () => Promise<boolean>\n readonly reset: () => void\n}\n\n/** Headless, per-instance form state. Definition changes preserve answers for unchanged field types. */\nexport function useCmsForm(input: MaybeRefOrGetter<FormDefinition>, options: UseCmsFormOptions = {}): UseCmsFormReturn {\n const fieldIdPrefix = getCurrentInstance() ? useId() : 'cms-form'\n const definition = computed(() => toValue(input))\n const steps = computed(() => definition.value.steps)\n const fields = computed(() => steps.value.flatMap((step) => step.fields))\n const values = ref<Record<string, FormValues[string]>>({})\n const errors = shallowRef<Record<string, string>>({})\n const stepIndex = ref(0)\n const currentStep = computed(() => steps.value[stepIndex.value])\n const isFirstStep = computed(() => stepIndex.value === 0)\n const isLastStep = computed(() => stepIndex.value === steps.value.length - 1)\n const submitting = ref(false)\n const isSuccess = ref(false)\n const isPreview = computed(() => definition.value.preview)\n const submitError = shallowRef<string>()\n const touched = ref(new Set<string>())\n const controls = new Map<string, CmsFormControl>()\n let controller: AbortController | undefined\n let generation = 0\n let previousFields = new Map<string, string>()\n\n const stop = watch(\n definition,\n (next, before) => {\n generation++\n controller?.abort()\n submitting.value = false\n\n const sameForm =\n before?.documentId === next.documentId &&\n JSON.stringify(before.nodePath) === JSON.stringify(next.nodePath) &&\n before.name === next.name\n\n values.value = Object.fromEntries(\n next.steps\n .flatMap((step) => step.fields)\n .map((field) => [\n field.id,\n sameForm && previousFields.get(field.id) === field.type\n ? (values.value[field.id] ?? null)\n : field.type === 'checkbox'\n ? false\n : field.type === 'number'\n ? null\n : '',\n ]),\n )\n previousFields = new Map(next.steps.flatMap((step) => step.fields).map((field) => [field.id, field.type]))\n stepIndex.value = Math.max(\n 0,\n next.steps.findIndex((step) => step.id === before?.steps[stepIndex.value]?.id),\n )\n errors.value = {}\n touched.value = new Set()\n submitError.value = undefined\n isSuccess.value = false\n },\n { immediate: true, deep: true, flush: 'sync' },\n )\n\n function validate(): boolean {\n touched.value = new Set(fields.value.map((field) => field.id))\n errors.value = validateFormValues(fields.value, values.value)\n\n return Object.keys(errors.value).length === 0\n }\n\n function control(input: string | FormField): CmsFormControl {\n const fieldId = Schema.is(Schema.String)(input) ? input : input.id\n const existing = controls.get(fieldId)\n\n if (existing) return existing\n\n if (!fields.value.some((candidate) => candidate.id === fieldId))\n throw new Error(`Unknown CMS form field ${fieldId}.`)\n\n const current = computed(() => {\n const candidate = fields.value.find((field) => field.id === fieldId)\n\n if (!candidate) throw new Error(`CMS form field ${fieldId} no longer exists.`)\n\n return candidate\n })\n\n const controlId = `${fieldIdPrefix}-${encodeURIComponent(fieldId)}`\n const helpId = `${controlId}-help`\n const errorId = `${controlId}-error`\n const helpAttrs: CmsFormControl['helpAttrs'] = { id: helpId }\n const errorAttrs: CmsFormControl['errorAttrs'] = { id: errorId, role: 'alert' }\n\n const refreshError = () => {\n const issue = validateFormValues([current.value], values.value)[fieldId]\n const nextErrors = { ...errors.value }\n\n if (issue) nextErrors[fieldId] = issue\n else delete nextErrors[fieldId]\n errors.value = nextErrors\n }\n\n const state = reactive({\n field: current,\n value: computed({\n get: () => values.value[fieldId] ?? emptyFormValue(current.value),\n set: (value) => {\n values.value[fieldId] = normalizeFormValue(current.value, value)\n\n if (touched.value.has(fieldId) || errors.value[fieldId]) refreshError()\n },\n }),\n dirty: computed(() => values.value[fieldId] !== emptyFormValue(current.value)),\n touched: computed(() => touched.value.has(fieldId)),\n valid: computed(() => validateFormValues([current.value], values.value)[fieldId] === undefined),\n error: computed(() => errors.value[fieldId]),\n attrs: computed<CmsFormControl['attrs']>(() => {\n const fieldError = errors.value[fieldId]\n\n const describedBy = [current.value.help ? helpId : undefined, fieldError ? errorId : undefined]\n .filter((part) => part !== undefined)\n .join(' ')\n\n return {\n id: controlId,\n name: fieldId,\n required: current.value.required === true,\n 'aria-invalid': fieldError ? 'true' : undefined,\n 'aria-describedby': describedBy || undefined,\n }\n }),\n helpAttrs,\n errorAttrs,\n touch: () => {\n touched.value = new Set([...touched.value, fieldId])\n refreshError()\n },\n })\n\n controls.set(fieldId, state)\n\n return state\n }\n\n function next(): boolean {\n if (submitting.value || isLastStep.value) return false\n const stepFields = currentStep.value?.fields ?? []\n touched.value = new Set([...touched.value, ...stepFields.map((field) => field.id)])\n const issues = validateFormValues(stepFields, values.value)\n errors.value = {\n ...Object.fromEntries(\n Object.entries(errors.value).filter(([id]) => !stepFields.some((field) => field.id === id)),\n ),\n ...issues,\n }\n\n if (Object.keys(issues).length) return false\n stepIndex.value++\n\n return true\n }\n\n function previous(): void {\n if (!submitting.value && !isFirstStep.value) stepIndex.value--\n }\n\n function reset(): void {\n generation++\n controller?.abort()\n submitting.value = false\n values.value = Object.fromEntries(fields.value.map((field) => [field.id, emptyFormValue(field)]))\n errors.value = {}\n touched.value = new Set()\n submitError.value = undefined\n isSuccess.value = false\n stepIndex.value = 0\n }\n\n async function submit(): Promise<boolean> {\n if (submitting.value || isSuccess.value) return false\n submitError.value = undefined\n\n if (!validate()) {\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n return false\n }\n\n if (isPreview.value) {\n isSuccess.value = true\n\n return true\n }\n\n const currentGeneration = ++generation\n controller = new AbortController()\n submitting.value = true\n\n try {\n const { documentId, nodePath, revision } = definition.value\n\n const result = await (options.submit ?? send)(\n { documentId, nodePath, revision, values: { ...values.value } },\n controller.signal,\n )\n\n if (generation !== currentGeneration) return false\n errors.value = result.status === 'invalid' ? { ...result.errors } : {}\n isSuccess.value = result.status === 'accepted'\n\n if (result.status === 'invalid')\n stepIndex.value = Math.max(\n 0,\n steps.value.findIndex((step) => step.fields.some((field) => errors.value[field.id])),\n )\n\n if (result.status !== 'accepted' && result.status !== 'invalid')\n submitError.value =\n result.status === 'stale'\n ? 'This form has changed. Reload the page before submitting.'\n : 'Submission failed. Please try again.'\n\n return isSuccess.value\n } catch {\n if (generation === currentGeneration) submitError.value = 'Submission failed. Please try again.'\n\n return false\n } finally {\n if (generation === currentGeneration) submitting.value = false\n }\n }\n\n if (getCurrentScope())\n onScopeDispose(() => {\n generation++\n controller?.abort()\n stop()\n })\n\n const visibleControls = computed(() => currentStep.value?.fields.map((entry) => control(entry)) ?? [])\n const invalidControls = computed(() => fields.value.map((entry) => control(entry)).filter((entry) => !entry.valid))\n const firstInvalidControlId = computed(() => invalidControls.value[0]?.attrs.id)\n const canSubmit = computed(() => !submitting.value && !isSuccess.value && invalidControls.value.length === 0)\n\n return {\n fields,\n steps,\n values,\n errors: readonly(errors),\n currentStep,\n stepIndex: readonly(stepIndex),\n isFirstStep,\n isLastStep,\n submitting: readonly(submitting),\n isSuccess: readonly(isSuccess),\n isPreview,\n submitError: readonly(submitError),\n canSubmit,\n visibleControls,\n invalidControls,\n firstInvalidControlId,\n control,\n next,\n previous,\n validate,\n submit,\n reset,\n }\n}\n\nfunction normalizeFormValue(field: FormField, input: FormValues[string] | undefined): FormValues[string] {\n if (field.type === 'checkbox') return input === true\n\n if (field.type === 'number') {\n if (input === '' || input == null) return null\n const value = Schema.is(Schema.Finite)(input) || Schema.is(Schema.String)(input) ? Number(input) : Number.NaN\n\n if (Number.isFinite(value)) return value\n\n return Schema.is(Schema.String)(input) ? input : null\n }\n\n return Schema.is(Schema.String)(input) ? input : ''\n}\n\nfunction emptyFormValue(field: FormField): FormValues[string] {\n if (field.type === 'checkbox') return false\n\n if (field.type === 'number') return null\n\n return ''\n}\n\nasync function send(submission: FormSubmission, signal: AbortSignal): Promise<FormResult> {\n const response = await fetch(CMS_FORM_SUBMIT_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(submission),\n signal,\n })\n\n if (!response.ok) throw new Error('Submission failed.')\n\n return Result.getOrThrow(Schema.decodeUnknownResult(FormResult)(await response.json()))\n}\n"],"mappings":"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"}
@@ -1,11 +1,13 @@
1
- import { CmsMessageKey } from "../../I18n.js";
1
+ import { a as CmsMessageParameters, i as CmsMessageKey, r as CmsLocale } from "../../I18n-zbqpWxki.js";
2
+ import { ComputedRef } from "vue";
2
3
  //#region src/runtime/i18n/useCmsI18n.d.ts
4
+ export interface UseCmsI18nReturn {
5
+ readonly locale: ComputedRef<CmsLocale>;
6
+ readonly localePath: (path: string, code?: CmsLocale) => string;
7
+ readonly switchLocalePath: (code: CmsLocale, destination?: string) => string;
8
+ readonly t: <Key extends CmsMessageKey>(key: Key, ...arguments_: keyof CmsMessageParameters<Key> extends never ? [parameters?: undefined] : [parameters: CmsMessageParameters<Key>]) => string;
9
+ }
3
10
  /** URL-owned locale is reactive and isolated to the current Nuxt application/request. */
4
- export declare function useCmsI18n(): {
5
- locale: import("vue").ComputedRef<string>;
6
- localePath: (path: string, code?: string) => string;
7
- switchLocalePath: (code: string, destination?: string) => string;
8
- t: (key: CmsMessageKey, parameters?: Readonly<Record<string, string | number>>) => string;
9
- };
11
+ export declare function useCmsI18n(): UseCmsI18nReturn;
10
12
  //#endregion
11
13
  //# sourceMappingURL=useCmsI18n.d.ts.map