@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.
- package/CHANGELOG.md +13 -0
- package/README.md +114 -41
- package/package.json +13 -1
- package/src/ApplicationTypes.d.ts +84 -0
- package/src/ApplicationTypes.js +1 -0
- package/src/{Configuration-CDMYfTre.js → Configuration-BU-UyGoH.js} +4 -4
- package/src/{Configuration-CDMYfTre.js.map → Configuration-BU-UyGoH.js.map} +1 -1
- package/src/Configuration.d.ts +43 -21
- package/src/Configuration.js.map +1 -1
- package/src/Content.d.ts +67 -0
- package/src/Content.js +291 -0
- package/src/Content.js.map +1 -0
- package/src/{ContentTransfer-C3Av9sWz.js → ContentTransfer-BhF9G56s.js} +8 -4
- package/src/ContentTransfer-BhF9G56s.js.map +1 -0
- package/src/ContentTransfer-CRQet3QJ.d.ts +48 -0
- package/src/{DocumentEngine-J7g-emdf.js → DocumentEngine-ClhFXW9M.js} +4 -4
- package/src/{DocumentEngine-J7g-emdf.js.map → DocumentEngine-ClhFXW9M.js.map} +1 -1
- package/src/DocumentModel.d.ts +14 -2
- package/src/DocumentModel.js +32 -4
- package/src/DocumentModel.js.map +1 -1
- package/src/{Forms-CfcI3tPU.js → Forms-BbkE7QfC.js} +47 -16
- package/src/Forms-BbkE7QfC.js.map +1 -0
- package/src/{Forms-Dj6NuW66.js → Forms-DoB56hfe.js} +24 -7
- package/src/Forms-DoB56hfe.js.map +1 -0
- package/src/{Forms-BsJMev5_.d.ts → Forms-R0HoTR-o.d.ts} +31 -13
- package/src/Forms.d.ts +23 -11
- package/src/Forms.js.map +1 -1
- package/src/I18n-zbqpWxki.d.ts +29 -0
- package/src/I18n.d.ts +2 -20
- package/src/Module.js +18 -7
- package/src/Module.js.map +1 -1
- package/src/{S3MediaObjects-CpPSzJto.js → S3MediaObjects-D5Ns4FM6.js} +61 -40
- package/src/S3MediaObjects-D5Ns4FM6.js.map +1 -0
- package/src/cli/content.js +63 -221
- package/src/cli/content.js.map +1 -1
- package/src/cli.js +120 -5
- package/src/cli.js.map +1 -1
- package/src/{connection-CBAy2qGy.js → connection-D5S9Iph-.js} +2 -2
- package/src/{connection-CBAy2qGy.js.map → connection-D5S9Iph-.js.map} +1 -1
- package/src/dev-lifecycle-CZ7iCzG9.js +515 -0
- package/src/dev-lifecycle-CZ7iCzG9.js.map +1 -0
- package/src/{installation-CNfIriVm.js → installation-BNuoRDOz.js} +601 -468
- package/src/installation-BNuoRDOz.js.map +1 -0
- package/src/internal/application-types.js +43 -0
- package/src/internal/application-types.js.map +1 -0
- package/src/internal/authoring-catalog.js +9 -4
- package/src/internal/authoring-catalog.js.map +1 -1
- package/src/internal/authoring-metadata.js +1 -1
- package/src/internal/configuration.js +149 -46
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/dev-lifecycle.js +3 -0
- package/src/internal/diagnostics.js +47 -0
- package/src/internal/diagnostics.js.map +1 -0
- package/src/internal/document-model.js +2 -2
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/form-capabilities.js +1 -1
- package/src/internal/i18n.js +27 -1
- package/src/internal/i18n.js.map +1 -1
- package/src/{location-BTqdfIzX.js → location-CPX7oj0o.js} +2 -2
- package/src/{location-BTqdfIzX.js.map → location-CPX7oj0o.js.map} +1 -1
- package/src/{models-B4IoTmp7.js → models-C9kF9JlQ.js} +2 -2
- package/src/{models-B4IoTmp7.js.map → models-C9kF9JlQ.js.map} +1 -1
- package/src/{models-Bah5B3bT.js → models-ChRxBChy.js} +9 -2
- package/src/models-ChRxBChy.js.map +1 -0
- package/src/runtime/delivery/context.js +1 -1
- package/src/runtime/delivery/plugin.js +28 -5
- package/src/runtime/delivery/plugin.js.map +1 -1
- package/src/runtime/delivery/preview.d.ts +1 -1
- package/src/runtime/delivery/types.d.ts +2 -85
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +8 -1
- package/src/runtime/delivery/useCmsDocumentSeo.js +19 -7
- package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
- package/src/runtime/delivery/useDocument.d.ts +2 -2
- package/src/runtime/delivery/useDocument.js.map +1 -1
- package/src/runtime/delivery/useDocumentQuery.d.ts +3 -3
- package/src/runtime/delivery/useDocumentQuery.js.map +1 -1
- package/src/runtime/forms/document.js +1 -1
- package/src/runtime/forms/useCmsForm.js +89 -45
- package/src/runtime/forms/useCmsForm.js.map +1 -1
- package/src/runtime/i18n/useCmsI18n.d.ts +9 -7
- package/src/runtime/i18n/useCmsI18n.js +5 -4
- package/src/runtime/i18n/useCmsI18n.js.map +1 -1
- package/src/runtime/installation.js +2 -2
- package/src/runtime/plugin.js +12 -4
- package/src/runtime/plugin.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +2 -2
- package/src/runtime/preview/plugin.client.js +3 -3
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +1 -1
- package/src/scalars-CA6kyipS.d.ts +7 -0
- package/src/{store-b2CSXgMt.js → store-B49J21NA.js} +3 -3
- package/src/{store-b2CSXgMt.js.map → store-B49J21NA.js.map} +1 -1
- package/src/types-DutFRtaG.d.ts +90 -0
- package/studio/{CreateDocumentDialog-GGey1uBc.js → CreateDocumentDialog-DJ8c0WZb.js} +3 -3
- package/studio/{documentPlanning-DRErYmBU.js → documentPlanning-CDb31mnl.js} +5935 -5869
- package/studio/host.css +1 -1
- package/studio/host.js +7608 -7250
- package/src/ContentTransfer-C3Av9sWz.js.map +0 -1
- package/src/Forms-CfcI3tPU.js.map +0 -1
- package/src/Forms-Dj6NuW66.js.map +0 -1
- package/src/S3MediaObjects-CpPSzJto.js.map +0 -1
- package/src/installation-CNfIriVm.js.map +0 -1
- package/src/models-Bah5B3bT.js.map +0 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/internal/application-types.ts
|
|
2
|
+
function generateCmsApplicationTypes(input) {
|
|
3
|
+
const locale = union(Object.keys(input.i18n.locales));
|
|
4
|
+
const messageKey = union(Object.keys(input.i18n.messageParameters));
|
|
5
|
+
const blockName = union(input.blockNames);
|
|
6
|
+
const parameters = Object.entries(input.i18n.messageParameters).map(([key, names]) => `${JSON.stringify(key)}: { ${names.map((name) => `readonly ${JSON.stringify(name)}: string | number`).join("; ")} }`).join("; ");
|
|
7
|
+
return [
|
|
8
|
+
`import '@phtngyn/cms/ApplicationTypes'`,
|
|
9
|
+
`import '@phtngyn/cms/I18n'`,
|
|
10
|
+
`declare module '@phtngyn/cms/ApplicationTypes' {`,
|
|
11
|
+
` interface CmsApplicationRegistry {`,
|
|
12
|
+
` configuration: typeof import(${JSON.stringify(input.configurationPath)}).default`,
|
|
13
|
+
` blockName: ${blockName}`,
|
|
14
|
+
` }`,
|
|
15
|
+
`}`,
|
|
16
|
+
`declare module '@phtngyn/cms/I18n' {`,
|
|
17
|
+
` interface CmsI18nRegistry {`,
|
|
18
|
+
` locale: ${locale}`,
|
|
19
|
+
` messageKey: ${messageKey}`,
|
|
20
|
+
` messageParameters: { ${parameters} }`,
|
|
21
|
+
` }`,
|
|
22
|
+
`}`,
|
|
23
|
+
`export type CmsBlockName = import('@phtngyn/cms/ApplicationTypes').CmsBlockName`,
|
|
24
|
+
`export type CmsCollectionName = import('@phtngyn/cms/ApplicationTypes').CmsCollectionName`,
|
|
25
|
+
`export type CmsCollection<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsCollection<Name>`,
|
|
26
|
+
`export type CmsDocumentPage<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentPage<Name>`,
|
|
27
|
+
`export type CmsDocumentQuery<Name extends CmsCollectionName = CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentQuery<Name>`,
|
|
28
|
+
`export type CmsDocumentQuerySort<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentQuerySort<Name>`,
|
|
29
|
+
`export type CmsFormDefinition<Name extends CmsFormName = CmsFormName> = import('@phtngyn/cms/ApplicationTypes').CmsFormDefinition<Name>`,
|
|
30
|
+
`export type CmsFormName = import('@phtngyn/cms/ApplicationTypes').CmsFormName`,
|
|
31
|
+
`export type CmsLocale = import('@phtngyn/cms/ApplicationTypes').CmsLocale`,
|
|
32
|
+
`export type CmsMessageKey = import('@phtngyn/cms/ApplicationTypes').CmsMessageKey`,
|
|
33
|
+
`export type CmsMessageParameters<Key extends CmsMessageKey> = import('@phtngyn/cms/ApplicationTypes').CmsMessageParameters<Key>`,
|
|
34
|
+
""
|
|
35
|
+
].join("\n");
|
|
36
|
+
}
|
|
37
|
+
function union(values) {
|
|
38
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right)).map((value) => JSON.stringify(value)).join(" | ") || "never";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { generateCmsApplicationTypes };
|
|
43
|
+
//# sourceMappingURL=application-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-types.js","names":[],"sources":["../../../../src/internal/application-types.ts"],"sourcesContent":["import type { CompiledCmsI18n } from './i18n'\n\nexport interface CmsApplicationTypeInput {\n readonly blockNames: ReadonlyArray<string>\n readonly configurationPath: string\n readonly i18n: CompiledCmsI18n\n}\n\nexport function generateCmsApplicationTypes(input: CmsApplicationTypeInput): string {\n const locale = union(Object.keys(input.i18n.locales))\n const messageKey = union(Object.keys(input.i18n.messageParameters))\n const blockName = union(input.blockNames)\n\n const parameters = Object.entries(input.i18n.messageParameters)\n .map(\n ([key, names]) =>\n `${JSON.stringify(key)}: { ${names.map((name) => `readonly ${JSON.stringify(name)}: string | number`).join('; ')} }`,\n )\n .join('; ')\n\n return [\n `import '@phtngyn/cms/ApplicationTypes'`,\n `import '@phtngyn/cms/I18n'`,\n `declare module '@phtngyn/cms/ApplicationTypes' {`,\n ` interface CmsApplicationRegistry {`,\n ` configuration: typeof import(${JSON.stringify(input.configurationPath)}).default`,\n ` blockName: ${blockName}`,\n ` }`,\n `}`,\n `declare module '@phtngyn/cms/I18n' {`,\n ` interface CmsI18nRegistry {`,\n ` locale: ${locale}`,\n ` messageKey: ${messageKey}`,\n ` messageParameters: { ${parameters} }`,\n ` }`,\n `}`,\n `export type CmsBlockName = import('@phtngyn/cms/ApplicationTypes').CmsBlockName`,\n `export type CmsCollectionName = import('@phtngyn/cms/ApplicationTypes').CmsCollectionName`,\n `export type CmsCollection<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsCollection<Name>`,\n `export type CmsDocumentPage<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentPage<Name>`,\n `export type CmsDocumentQuery<Name extends CmsCollectionName = CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentQuery<Name>`,\n `export type CmsDocumentQuerySort<Name extends CmsCollectionName> = import('@phtngyn/cms/ApplicationTypes').CmsDocumentQuerySort<Name>`,\n `export type CmsFormDefinition<Name extends CmsFormName = CmsFormName> = import('@phtngyn/cms/ApplicationTypes').CmsFormDefinition<Name>`,\n `export type CmsFormName = import('@phtngyn/cms/ApplicationTypes').CmsFormName`,\n `export type CmsLocale = import('@phtngyn/cms/ApplicationTypes').CmsLocale`,\n `export type CmsMessageKey = import('@phtngyn/cms/ApplicationTypes').CmsMessageKey`,\n `export type CmsMessageParameters<Key extends CmsMessageKey> = import('@phtngyn/cms/ApplicationTypes').CmsMessageParameters<Key>`,\n '',\n ].join('\\n')\n}\n\nfunction union(values: ReadonlyArray<string>): string {\n return (\n [...new Set(values)]\n .sort((left, right) => left.localeCompare(right))\n .map((value) => JSON.stringify(value))\n .join(' | ') || 'never'\n )\n}\n"],"mappings":";AAQA,SAAgB,4BAA4B,OAAwC;CAClF,MAAM,SAAS,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,CAAC;CACpD,MAAM,aAAa,MAAM,OAAO,KAAK,MAAM,KAAK,iBAAiB,CAAC;CAClE,MAAM,YAAY,MAAM,MAAM,UAAU;CAExC,MAAM,aAAa,OAAO,QAAQ,MAAM,KAAK,iBAAiB,CAAC,CAC5D,KACE,CAAC,KAAK,WACL,GAAG,KAAK,UAAU,GAAG,EAAE,MAAM,MAAM,KAAK,SAAS,YAAY,KAAK,UAAU,IAAI,EAAE,kBAAkB,CAAC,CAAC,KAAK,IAAI,EAAE,GACrH,CAAC,CACA,KAAK,IAAI;CAEZ,OAAO;EACL;EACA;EACA;EACA;EACA,oCAAoC,KAAK,UAAU,MAAM,iBAAiB,EAAE;EAC5E,kBAAkB;EAClB;EACA;EACA;EACA;EACA,eAAe;EACf,mBAAmB;EACnB,4BAA4B,WAAW;EACvC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,MAAM,QAAuC;CACpD,OACE,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CACjB,MAAM,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC,CAAC,CAChD,KAAK,UAAU,KAAK,UAAU,KAAK,CAAC,CAAC,CACrC,KAAK,KAAK,KAAK;AAEtB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as formAuthoring } from "../Forms-
|
|
2
|
-
import { l as validateCollectionBody, n as ComponentDefinition, t as AuthoringCatalog } from "../Configuration-
|
|
1
|
+
import { n as formAuthoring } from "../Forms-DoB56hfe.js";
|
|
2
|
+
import { l as validateCollectionBody, n as ComponentDefinition, t as AuthoringCatalog } from "../Configuration-BU-UyGoH.js";
|
|
3
3
|
import { resolveBlockAuthoring } from "./authoring-metadata.js";
|
|
4
4
|
import { Crypto, Effect, Encoding, FileSystem, Path, Schema } from "effect";
|
|
5
5
|
import { addTemplate, addVitePlugin, updateTemplates } from "@nuxt/kit";
|
|
@@ -7,7 +7,7 @@ import { createCheckerByJson } from "vue-component-meta";
|
|
|
7
7
|
|
|
8
8
|
//#region src/internal/authoring-catalog.ts
|
|
9
9
|
/** A complete, validated snapshot shared by Vite and Nitro through ordinary imports. */
|
|
10
|
-
const registerAuthoringCatalog = Effect.fn("CmsAuthoring.register")(function* (nuxt, documents, forms = {}) {
|
|
10
|
+
const registerAuthoringCatalog = Effect.fn("CmsAuthoring.register")(function* (nuxt, documents, forms = {}, onBlockNames, additionalTemplatePaths = []) {
|
|
11
11
|
const fs = yield* FileSystem.FileSystem;
|
|
12
12
|
const path = yield* Path.Path;
|
|
13
13
|
const crypto = yield* Crypto.Crypto;
|
|
@@ -72,6 +72,7 @@ const registerAuthoringCatalog = Effect.fn("CmsAuthoring.register")(function* (n
|
|
|
72
72
|
}
|
|
73
73
|
for (const name of Object.keys(forms)) if (!definitions.some((definition) => definition.name === name)) throw new Error(`Missing Vue form renderer ${name}.`);
|
|
74
74
|
const components = definitions.sort((left, right) => left.name.localeCompare(right.name));
|
|
75
|
+
onBlockNames?.(components.filter((component) => forms[component.name] === void 0).map((component) => component.name));
|
|
75
76
|
for (const collection of documents.types) {
|
|
76
77
|
const issues = validateCollectionBody(components, collection.body);
|
|
77
78
|
if (issues.length) throw new Error(`${collection.label}: ${issues.join(" ")}`);
|
|
@@ -120,7 +121,11 @@ const registerAuthoringCatalog = Effect.fn("CmsAuthoring.register")(function* (n
|
|
|
120
121
|
return run(Effect.logError("Authoring update rejected; keeping the last valid catalog.", error));
|
|
121
122
|
}
|
|
122
123
|
function update() {
|
|
123
|
-
return rebuild().then((changed) => changed ? updateTemplates({ filter: (candidate) => [
|
|
124
|
+
return rebuild().then((changed) => changed ? updateTemplates({ filter: (candidate) => [
|
|
125
|
+
template.dst,
|
|
126
|
+
blocks.dst,
|
|
127
|
+
...additionalTemplatePaths
|
|
128
|
+
].includes(candidate.dst) }) : void 0).catch((error) => report(error instanceof Error ? error : new Error(String(error))));
|
|
124
129
|
}
|
|
125
130
|
nuxt.hook("components:extend", (components) => {
|
|
126
131
|
discovered = components;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authoring-catalog.js","names":[],"sources":["../../../../src/internal/authoring-catalog.ts"],"sourcesContent":["import { formAuthoring } from '@internal/document/Forms'\nimport type { FormCapabilities } from '@internal/protocol/Forms'\nimport { validateCollectionBody } from '@internal/document/AuthoringSchema'\nimport type { DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { Nuxt } from '@nuxt/schema'\nimport type { Component } from '@nuxt/schema'\nimport { AuthoringCatalog, ComponentDefinition } from '@internal/protocol/Configuration'\nimport { addTemplate, addVitePlugin, updateTemplates } from '@nuxt/kit'\nimport { Crypto, Effect, Encoding, FileSystem, Path, Schema } from 'effect'\nimport { createCheckerByJson } from 'vue-component-meta'\nimport { resolveBlockAuthoring } from './authoring-metadata'\n\ntype AuthoringServer = {\n ws: {\n send: (\n payload:\n | { type: 'update'; updates: [] }\n | { type: 'error'; err: { message: string; stack: string; plugin: string } },\n ) => void\n }\n watcher: { add: (paths: string[]) => void }\n}\n\n/** A complete, validated snapshot shared by Vite and Nitro through ordinary imports. */\nexport const registerAuthoringCatalog = Effect.fn('CmsAuthoring.register')(function* (\n nuxt: Nuxt,\n documents: DocumentConfiguration,\n forms: Readonly<Record<string, FormCapabilities>> = {},\n) {\n const fs = yield* FileSystem.FileSystem\n const path = yield* Path.Path\n const crypto = yield* Crypto.Crypto\n const run = Effect.runPromiseWith(yield* Effect.context<never>())\n let contents = 'export default { revision: \"empty\", components: [] }\\n'\n let blockContents = 'export default {}\\n'\n let discovered: Component[] = []\n let dependencies = new Set<string>()\n let queue = Promise.resolve()\n const servers = new Set<AuthoringServer>()\n let initialized = false\n let rejected = false\n\n const template = addTemplate({\n filename: 'cms/authoring.mjs',\n write: true,\n getContents: () => contents,\n })\n\n const blocks = addTemplate({ filename: 'cms/blocks.mjs', write: true, getContents: () => blockContents })\n nuxt.options.alias['#cms/blocks'] = blocks.dst\n nuxt.options.alias['#cms/authoring'] = template.dst\n nuxt.hook('nitro:config', (config) => {\n config.externals ||= {}\n config.externals.inline ||= []\n config.externals.inline.push(template.dst)\n })\n\n const compile = Effect.fn('CmsAuthoring.compile')(function* () {\n const checker = createCheckerByJson(\n nuxt.options.rootDir,\n {\n compilerOptions: {\n strict: true,\n target: 'ESNext',\n module: 'ESNext',\n moduleResolution: 'Bundler',\n baseUrl: nuxt.options.rootDir,\n paths: Object.fromEntries(\n Object.entries(nuxt.options.alias).map(([key, value]) => [`${key}/*`, [`${value}/*`]]),\n ),\n },\n files: [],\n },\n { schema: true },\n )\n\n const definitions: ComponentDefinition[] = []\n const registrations: { name: string; filePath: string }[] = []\n\n try {\n for (const component of discovered) {\n if (!component.filePath.endsWith('.vue') || component.filePath.includes('/node_modules/')) continue\n\n if (!(yield* fs.exists(component.filePath))) continue\n const source = yield* fs.readFileString(component.filePath)\n const form = forms[component.kebabName]\n\n const definition = form\n ? ComponentDefinition.make({ name: component.kebabName, authoring: formAuthoring(form) })\n : yield* resolveBlockAuthoring(checker, component.filePath, component.kebabName, source)\n\n if (!definition) continue\n\n if (definitions.some((existing) => existing.name === definition.name))\n throw new Error(`Duplicate authoring block ${definition.name}.`)\n definitions.push(definition)\n component.global = false\n registrations.push({ name: definition.name, filePath: component.filePath })\n }\n\n for (const name of Object.keys(forms))\n if (!definitions.some((definition) => definition.name === name))\n throw new Error(`Missing Vue form renderer ${name}.`)\n const components = definitions.sort((left, right) => left.name.localeCompare(right.name))\n\n for (const collection of documents.types) {\n const issues = validateCollectionBody(components, collection.body)\n\n if (issues.length) throw new Error(`${collection.label}: ${issues.join(' ')}`)\n }\n\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Array(ComponentDefinition)))(components)\n const revision = Encoding.encodeHex(yield* crypto.digest('SHA-256', new TextEncoder().encode(encoded)))\n const catalog = yield* Schema.encodeEffect(Schema.fromJsonString(AuthoringCatalog))({ revision, components })\n const next = `export default ${catalog}\\n`\n registrations.sort((left, right) => left.name.localeCompare(right.name))\n\n const nextBlocks = [\n ...registrations.map((component, index) => `import Block${index} from ${JSON.stringify(component.filePath)}`),\n `export default { ${registrations.map((component, index) => `${JSON.stringify(component.name)}: Block${index}`).join(', ')} }`,\n ].join('\\n')\n\n const changed = next !== contents || nextBlocks !== blockContents\n blockContents = nextBlocks\n\n if (rejected) {\n rejected = false\n\n for (const server of servers) server.ws.send({ type: 'update', updates: [] })\n }\n\n if (!changed) return false\n contents = next\n\n return true\n } finally {\n const discoveredDependencies = new Set(\n checker\n .getProgram()\n ?.getSourceFiles()\n .map((file) => path.resolve(file.fileName))\n .filter((file) => !file.includes('/node_modules/')),\n )\n\n // Keep failed candidate dependencies too, so fixing an imported type can recover the catalog.\n dependencies = new Set([...dependencies, ...discoveredDependencies])\n\n for (const server of servers) server.watcher.add([...dependencies])\n }\n })\n\n function rebuild() {\n const current = queue.then(() => run(compile()))\n queue = current.then(\n () => undefined,\n () => undefined,\n )\n\n return current\n }\n\n function report(error: Error) {\n rejected = true\n\n for (const server of servers)\n server.ws.send({\n type: 'error',\n err: { message: error.message, stack: error.stack ?? '', plugin: 'cms-authoring' },\n })\n\n return run(Effect.logError('Authoring update rejected; keeping the last valid catalog.', error))\n }\n\n function update() {\n return rebuild()\n .then((changed) =>\n changed\n ? updateTemplates({ filter: (candidate) => [template.dst, blocks.dst].includes(candidate.dst) })\n : undefined,\n )\n .catch((error) => report(error instanceof Error ? error : new Error(String(error))))\n }\n\n nuxt.hook('components:extend', (components) => {\n discovered = components\n // This hook runs inside template generation. Its caller writes the new snapshot.\n const candidate = rebuild().then(() => undefined)\n\n if (initialized)\n return candidate.catch((error) => report(error instanceof Error ? error : new Error(String(error))))\n initialized = true\n\n return candidate\n })\n addVitePlugin({\n name: 'cms-authoring-catalog',\n configureServer(server) {\n servers.add(server)\n server.watcher.add([...dependencies])\n\n const changed = (filename: string) => {\n const absolute = path.resolve(filename)\n\n if (dependencies.has(absolute) || discovered.some((component) => component.filePath === absolute)) void update()\n }\n\n server.watcher.on('change', changed)\n server.httpServer?.once('close', () => {\n servers.delete(server)\n server.watcher.off('change', changed)\n })\n },\n })\n\n return template\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"authoring-catalog.js","names":[],"sources":["../../../../src/internal/authoring-catalog.ts"],"sourcesContent":["import { formAuthoring } from '@internal/document/Forms'\nimport type { FormCapabilities } from '@internal/protocol/Forms'\nimport { validateCollectionBody } from '@internal/document/AuthoringSchema'\nimport type { DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { Nuxt } from '@nuxt/schema'\nimport type { Component } from '@nuxt/schema'\nimport { AuthoringCatalog, ComponentDefinition } from '@internal/protocol/Configuration'\nimport { addTemplate, addVitePlugin, updateTemplates } from '@nuxt/kit'\nimport { Crypto, Effect, Encoding, FileSystem, Path, Schema } from 'effect'\nimport { createCheckerByJson } from 'vue-component-meta'\nimport { resolveBlockAuthoring } from './authoring-metadata'\n\ntype AuthoringServer = {\n ws: {\n send: (\n payload:\n | { type: 'update'; updates: [] }\n | { type: 'error'; err: { message: string; stack: string; plugin: string } },\n ) => void\n }\n watcher: { add: (paths: string[]) => void }\n}\n\n/** A complete, validated snapshot shared by Vite and Nitro through ordinary imports. */\nexport const registerAuthoringCatalog = Effect.fn('CmsAuthoring.register')(function* (\n nuxt: Nuxt,\n documents: DocumentConfiguration,\n forms: Readonly<Record<string, FormCapabilities>> = {},\n onBlockNames?: (names: ReadonlyArray<string>) => void,\n additionalTemplatePaths: ReadonlyArray<string> = [],\n) {\n const fs = yield* FileSystem.FileSystem\n const path = yield* Path.Path\n const crypto = yield* Crypto.Crypto\n const run = Effect.runPromiseWith(yield* Effect.context<never>())\n let contents = 'export default { revision: \"empty\", components: [] }\\n'\n let blockContents = 'export default {}\\n'\n let discovered: Component[] = []\n let dependencies = new Set<string>()\n let queue = Promise.resolve()\n const servers = new Set<AuthoringServer>()\n let initialized = false\n let rejected = false\n\n const template = addTemplate({\n filename: 'cms/authoring.mjs',\n write: true,\n getContents: () => contents,\n })\n\n const blocks = addTemplate({ filename: 'cms/blocks.mjs', write: true, getContents: () => blockContents })\n nuxt.options.alias['#cms/blocks'] = blocks.dst\n nuxt.options.alias['#cms/authoring'] = template.dst\n nuxt.hook('nitro:config', (config) => {\n config.externals ||= {}\n config.externals.inline ||= []\n config.externals.inline.push(template.dst)\n })\n\n const compile = Effect.fn('CmsAuthoring.compile')(function* () {\n const checker = createCheckerByJson(\n nuxt.options.rootDir,\n {\n compilerOptions: {\n strict: true,\n target: 'ESNext',\n module: 'ESNext',\n moduleResolution: 'Bundler',\n baseUrl: nuxt.options.rootDir,\n paths: Object.fromEntries(\n Object.entries(nuxt.options.alias).map(([key, value]) => [`${key}/*`, [`${value}/*`]]),\n ),\n },\n files: [],\n },\n { schema: true },\n )\n\n const definitions: ComponentDefinition[] = []\n const registrations: { name: string; filePath: string }[] = []\n\n try {\n for (const component of discovered) {\n if (!component.filePath.endsWith('.vue') || component.filePath.includes('/node_modules/')) continue\n\n if (!(yield* fs.exists(component.filePath))) continue\n const source = yield* fs.readFileString(component.filePath)\n const form = forms[component.kebabName]\n\n const definition = form\n ? ComponentDefinition.make({ name: component.kebabName, authoring: formAuthoring(form) })\n : yield* resolveBlockAuthoring(checker, component.filePath, component.kebabName, source)\n\n if (!definition) continue\n\n if (definitions.some((existing) => existing.name === definition.name))\n throw new Error(`Duplicate authoring block ${definition.name}.`)\n definitions.push(definition)\n component.global = false\n registrations.push({ name: definition.name, filePath: component.filePath })\n }\n\n for (const name of Object.keys(forms))\n if (!definitions.some((definition) => definition.name === name))\n throw new Error(`Missing Vue form renderer ${name}.`)\n const components = definitions.sort((left, right) => left.name.localeCompare(right.name))\n onBlockNames?.(\n components.filter((component) => forms[component.name] === undefined).map((component) => component.name),\n )\n\n for (const collection of documents.types) {\n const issues = validateCollectionBody(components, collection.body)\n\n if (issues.length) throw new Error(`${collection.label}: ${issues.join(' ')}`)\n }\n\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Array(ComponentDefinition)))(components)\n const revision = Encoding.encodeHex(yield* crypto.digest('SHA-256', new TextEncoder().encode(encoded)))\n const catalog = yield* Schema.encodeEffect(Schema.fromJsonString(AuthoringCatalog))({ revision, components })\n const next = `export default ${catalog}\\n`\n registrations.sort((left, right) => left.name.localeCompare(right.name))\n\n const nextBlocks = [\n ...registrations.map((component, index) => `import Block${index} from ${JSON.stringify(component.filePath)}`),\n `export default { ${registrations.map((component, index) => `${JSON.stringify(component.name)}: Block${index}`).join(', ')} }`,\n ].join('\\n')\n\n const changed = next !== contents || nextBlocks !== blockContents\n blockContents = nextBlocks\n\n if (rejected) {\n rejected = false\n\n for (const server of servers) server.ws.send({ type: 'update', updates: [] })\n }\n\n if (!changed) return false\n contents = next\n\n return true\n } finally {\n const discoveredDependencies = new Set(\n checker\n .getProgram()\n ?.getSourceFiles()\n .map((file) => path.resolve(file.fileName))\n .filter((file) => !file.includes('/node_modules/')),\n )\n\n // Keep failed candidate dependencies too, so fixing an imported type can recover the catalog.\n dependencies = new Set([...dependencies, ...discoveredDependencies])\n\n for (const server of servers) server.watcher.add([...dependencies])\n }\n })\n\n function rebuild() {\n const current = queue.then(() => run(compile()))\n queue = current.then(\n () => undefined,\n () => undefined,\n )\n\n return current\n }\n\n function report(error: Error) {\n rejected = true\n\n for (const server of servers)\n server.ws.send({\n type: 'error',\n err: { message: error.message, stack: error.stack ?? '', plugin: 'cms-authoring' },\n })\n\n return run(Effect.logError('Authoring update rejected; keeping the last valid catalog.', error))\n }\n\n function update() {\n return rebuild()\n .then((changed) =>\n changed\n ? updateTemplates({\n filter: (candidate) => [template.dst, blocks.dst, ...additionalTemplatePaths].includes(candidate.dst),\n })\n : undefined,\n )\n .catch((error) => report(error instanceof Error ? error : new Error(String(error))))\n }\n\n nuxt.hook('components:extend', (components) => {\n discovered = components\n // This hook runs inside template generation. Its caller writes the new snapshot.\n const candidate = rebuild().then(() => undefined)\n\n if (initialized)\n return candidate.catch((error) => report(error instanceof Error ? error : new Error(String(error))))\n initialized = true\n\n return candidate\n })\n addVitePlugin({\n name: 'cms-authoring-catalog',\n configureServer(server) {\n servers.add(server)\n server.watcher.add([...dependencies])\n\n const changed = (filename: string) => {\n const absolute = path.resolve(filename)\n\n if (dependencies.has(absolute) || discovered.some((component) => component.filePath === absolute)) void update()\n }\n\n server.watcher.on('change', changed)\n server.httpServer?.once('close', () => {\n servers.delete(server)\n server.watcher.off('change', changed)\n })\n },\n })\n\n return template\n})\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as BlockAuthoring, c as parseAuthoringContent, n as ComponentDefinition, s as createAuthoringSchema } from "../Configuration-
|
|
1
|
+
import { a as BlockAuthoring, c as parseAuthoringContent, n as ComponentDefinition, s as createAuthoringSchema } from "../Configuration-BU-UyGoH.js";
|
|
2
2
|
import { compileCmsBlock, readAuthoringDefault } from "./authoring-compiler.js";
|
|
3
3
|
import { Effect, Result, Schema } from "effect";
|
|
4
4
|
import ts from "typescript";
|
|
@@ -1,49 +1,53 @@
|
|
|
1
|
+
import { R as SeoConfiguration } from "../models-ChRxBChy.js";
|
|
2
|
+
import { j as StudioBootstrap, t as maxS3SingleCopyBytes, u as makeDefaultSeoOptions } from "../S3MediaObjects-D5Ns4FM6.js";
|
|
1
3
|
import { validateFormCapabilities } from "./form-capabilities.js";
|
|
2
|
-
import { R as SeoConfiguration } from "../models-Bah5B3bT.js";
|
|
3
|
-
import { j as StudioBootstrap, t as maxS3SingleCopyBytes, u as makeDefaultSeoOptions } from "../S3MediaObjects-CpPSzJto.js";
|
|
4
4
|
import { compileCmsI18n } from "./i18n.js";
|
|
5
|
-
import { i as PreviewOrigin } from "../models-
|
|
5
|
+
import { i as PreviewOrigin } from "../models-C9kF9JlQ.js";
|
|
6
6
|
import { compileCmsDocumentModel } from "./document-model.js";
|
|
7
|
-
import { Predicate, Result, Schema } from "effect";
|
|
7
|
+
import { Config, Effect, Predicate, Redacted, Result, Schema } from "effect";
|
|
8
8
|
|
|
9
9
|
//#region src/internal/configuration.ts
|
|
10
10
|
const DEFAULT_CLEANUP_INTERVAL_MILLIS = 864e5;
|
|
11
11
|
const DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS = 6e4;
|
|
12
12
|
const DEFAULT_MEDIA_MAX_UPLOAD_BYTES = 1e7;
|
|
13
|
-
const
|
|
14
|
-
const InstallationConfiguration = Schema.Struct({
|
|
15
|
-
baseUrl: PreviewOrigin,
|
|
13
|
+
const AuthoredInstallationConfiguration = Schema.Struct({
|
|
16
14
|
cleanup: Schema.optionalKey(Schema.Union([Schema.Literals([false]), Schema.Struct({
|
|
17
15
|
initialDelayMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),
|
|
18
16
|
intervalMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0)))
|
|
19
17
|
})])),
|
|
20
|
-
|
|
21
|
-
initializationToken: Schema.NonEmptyString.check(Schema.isMinLength(32)),
|
|
18
|
+
database: Schema.Struct({ schema: Schema.NonEmptyString.check(Schema.makeFilter((value) => /^[a-z_][a-z0-9_]{0,62}$/u.test(value), { expected: "a lowercase PostgreSQL identifier" })) }),
|
|
22
19
|
media: Schema.optionalKey(Schema.Union([Schema.Literals([false]), Schema.Struct({
|
|
23
20
|
maxUploadBytes: Schema.optionalKey(Schema.Int.check(Schema.isBetween({
|
|
24
21
|
minimum: 1,
|
|
25
22
|
maximum: maxS3SingleCopyBytes
|
|
26
23
|
}))),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
})),
|
|
35
|
-
endpoint: optionalString,
|
|
36
|
-
forcePathStyle: Schema.optionalKey(Schema.Boolean),
|
|
37
|
-
provisionBucket: Schema.optionalKey(Schema.Boolean),
|
|
38
|
-
region: Schema.NonEmptyString
|
|
39
|
-
})
|
|
40
|
-
})])),
|
|
41
|
-
seo: Schema.optionalKey(SeoConfiguration),
|
|
24
|
+
prefix: Schema.NonEmptyString.check(Schema.makeFilter((value) => !value.startsWith("/") && value.endsWith("/") && !value.includes(".."), { expected: "a relative object prefix ending in /" }))
|
|
25
|
+
})]))
|
|
26
|
+
});
|
|
27
|
+
const RuntimeConfiguration = Schema.Struct({
|
|
28
|
+
baseUrl: PreviewOrigin,
|
|
29
|
+
databaseUrl: Schema.NonEmptyString,
|
|
30
|
+
initializationToken: Schema.NonEmptyString.check(Schema.isMinLength(32)),
|
|
42
31
|
secret: Schema.NonEmptyString.check(Schema.isMinLength(32))
|
|
43
32
|
});
|
|
33
|
+
const RuntimeMediaConfiguration = Schema.Struct({
|
|
34
|
+
accessKeyId: Schema.optionalKey(Schema.NonEmptyString),
|
|
35
|
+
bucket: Schema.NonEmptyString,
|
|
36
|
+
endpoint: Schema.optionalKey(Schema.NonEmptyString),
|
|
37
|
+
forcePathStyle: Schema.optionalKey(Schema.Boolean),
|
|
38
|
+
provisionBucket: Schema.optionalKey(Schema.Boolean),
|
|
39
|
+
publicBaseUrl: Schema.NonEmptyString,
|
|
40
|
+
region: Schema.NonEmptyString,
|
|
41
|
+
secretAccessKey: Schema.optionalKey(Schema.NonEmptyString),
|
|
42
|
+
sessionToken: Schema.optionalKey(Schema.NonEmptyString)
|
|
43
|
+
});
|
|
44
|
+
var CmsRuntimeConfigurationMissing = class extends Schema.TaggedError()("CmsRuntimeConfigurationMissing", {
|
|
45
|
+
environmentVariable: Schema.String,
|
|
46
|
+
message: Schema.String,
|
|
47
|
+
path: Schema.String
|
|
48
|
+
}) {};
|
|
44
49
|
function compileCmsConfiguration(configuration) {
|
|
45
|
-
const
|
|
46
|
-
if (Result.isFailure(decodedConfiguration)) throw new Error(`Invalid CMS configuration: ${String(decodedConfiguration.failure)}`);
|
|
50
|
+
const installation = decodeOrThrow(AuthoredInstallationConfiguration, configuration.installation, "authored installation");
|
|
47
51
|
for (const [name, form] of Object.entries(configuration.forms ?? {})) {
|
|
48
52
|
if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(name)) throw new Error(`Form ${name} needs a kebab-case Vue component name.`);
|
|
49
53
|
validateFormCapabilities(form.definition);
|
|
@@ -51,51 +55,150 @@ function compileCmsConfiguration(configuration) {
|
|
|
51
55
|
}
|
|
52
56
|
const i18n = compileCmsI18n(configuration.i18n);
|
|
53
57
|
const documents = compileCmsDocumentModel(configuration.documents, configuration.i18n);
|
|
58
|
+
const seo = configuration.seo === void 0 ? void 0 : decodeOrThrow(SeoConfiguration, configuration.seo, "SEO");
|
|
54
59
|
return {
|
|
55
60
|
i18n,
|
|
56
61
|
documentModel: documents.executable,
|
|
57
62
|
documents: documents.authoring,
|
|
58
|
-
installation
|
|
63
|
+
installation,
|
|
64
|
+
...seo === void 0 ? void 0 : { seo }
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Adds the keys Nitro needs in order to apply NUXT_CMS_* runtime environment overrides. */
|
|
68
|
+
function cmsRuntimeConfigurationDefaults(authored, input) {
|
|
69
|
+
const configured = Predicate.isObject(input) ? input : {};
|
|
70
|
+
const mediaEnabled = authored.installation.media !== false && authored.installation.media !== void 0;
|
|
71
|
+
const configuredMedia = Predicate.isObject(configured.media) ? configured.media : void 0;
|
|
72
|
+
const string = (value) => Schema.is(Schema.String)(value) ? value : "";
|
|
73
|
+
const boolean = (value) => Schema.is(Schema.Boolean)(value) ? value : false;
|
|
74
|
+
return {
|
|
75
|
+
baseUrl: string(configured.baseUrl),
|
|
76
|
+
databaseUrl: string(configured.databaseUrl),
|
|
77
|
+
initializationToken: string(configured.initializationToken),
|
|
78
|
+
media: mediaEnabled ? configured.media === false ? false : {
|
|
79
|
+
accessKeyId: string(configuredMedia?.accessKeyId),
|
|
80
|
+
bucket: string(configuredMedia?.bucket),
|
|
81
|
+
endpoint: string(configuredMedia?.endpoint),
|
|
82
|
+
forcePathStyle: boolean(configuredMedia?.forcePathStyle),
|
|
83
|
+
provisionBucket: boolean(configuredMedia?.provisionBucket),
|
|
84
|
+
publicBaseUrl: string(configuredMedia?.publicBaseUrl),
|
|
85
|
+
region: string(configuredMedia?.region),
|
|
86
|
+
secretAccessKey: string(configuredMedia?.secretAccessKey),
|
|
87
|
+
sessionToken: string(configuredMedia?.sessionToken)
|
|
88
|
+
} : false,
|
|
89
|
+
secret: string(configured.secret)
|
|
59
90
|
};
|
|
60
91
|
}
|
|
61
|
-
|
|
92
|
+
/** Reads the same NUXT_CMS_* values that Nitro applies to runtimeConfig at process startup. */
|
|
93
|
+
const cmsRuntimeConfigurationFromEnvironment = Effect.fn("CmsConfiguration.runtimeFromEnvironment")(function* (defaults) {
|
|
94
|
+
const string = (name, fallback) => Config.String(name).pipe(Config.withDefault(fallback));
|
|
95
|
+
const secret = (name, fallback) => Config.Redacted(name).pipe(Config.withDefault(Redacted.make(fallback)), Effect.map(Redacted.value));
|
|
96
|
+
return {
|
|
97
|
+
baseUrl: yield* string("NUXT_CMS_BASE_URL", defaults.baseUrl),
|
|
98
|
+
databaseUrl: yield* string("NUXT_CMS_DATABASE_URL", defaults.databaseUrl),
|
|
99
|
+
initializationToken: yield* secret("NUXT_CMS_INITIALIZATION_TOKEN", defaults.initializationToken),
|
|
100
|
+
media: defaults.media === false || defaults.media === void 0 ? false : {
|
|
101
|
+
accessKeyId: yield* string("NUXT_CMS_MEDIA_ACCESS_KEY_ID", defaults.media.accessKeyId ?? ""),
|
|
102
|
+
bucket: yield* string("NUXT_CMS_MEDIA_BUCKET", defaults.media.bucket),
|
|
103
|
+
endpoint: yield* string("NUXT_CMS_MEDIA_ENDPOINT", defaults.media.endpoint ?? ""),
|
|
104
|
+
forcePathStyle: yield* Config.Boolean("NUXT_CMS_MEDIA_FORCE_PATH_STYLE").pipe(Config.withDefault(defaults.media.forcePathStyle ?? false)),
|
|
105
|
+
provisionBucket: yield* Config.Boolean("NUXT_CMS_MEDIA_PROVISION_BUCKET").pipe(Config.withDefault(defaults.media.provisionBucket ?? false)),
|
|
106
|
+
publicBaseUrl: yield* string("NUXT_CMS_MEDIA_PUBLIC_BASE_URL", defaults.media.publicBaseUrl),
|
|
107
|
+
region: yield* string("NUXT_CMS_MEDIA_REGION", defaults.media.region),
|
|
108
|
+
secretAccessKey: yield* secret("NUXT_CMS_MEDIA_SECRET_ACCESS_KEY", defaults.media.secretAccessKey ?? ""),
|
|
109
|
+
sessionToken: yield* secret("NUXT_CMS_MEDIA_SESSION_TOKEN", defaults.media.sessionToken ?? "")
|
|
110
|
+
},
|
|
111
|
+
secret: yield* secret("NUXT_CMS_SECRET", defaults.secret)
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
function resolveCmsInstallation(authored, runtimeInput, authoring) {
|
|
62
115
|
const compiled = compileCmsConfiguration(authored);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
116
|
+
const runtimeObject = Predicate.isObject(runtimeInput) ? runtimeInput : {};
|
|
117
|
+
requireRuntimeValue(runtimeObject.baseUrl, "cms.baseUrl", "NUXT_CMS_BASE_URL");
|
|
118
|
+
requireRuntimeValue(runtimeObject.databaseUrl, "cms.databaseUrl", "NUXT_CMS_DATABASE_URL");
|
|
119
|
+
requireRuntimeValue(runtimeObject.initializationToken, "cms.initializationToken", "NUXT_CMS_INITIALIZATION_TOKEN");
|
|
120
|
+
requireRuntimeValue(runtimeObject.secret, "cms.secret", "NUXT_CMS_SECRET");
|
|
121
|
+
const runtimeResult = Schema.decodeUnknownResult(RuntimeConfiguration)(runtimeInput);
|
|
122
|
+
if (Result.isFailure(runtimeResult)) throw new Error(`Invalid CMS runtime installation configuration: ${String(runtimeResult.failure)}`);
|
|
123
|
+
const runtime = runtimeResult.success;
|
|
124
|
+
const cleanup = compiled.installation.cleanup === false ? void 0 : compiled.installation.cleanup;
|
|
125
|
+
const authoredMedia = compiled.installation.media === false ? void 0 : compiled.installation.media;
|
|
126
|
+
const runtimeMedia = authoredMedia ? decodeRuntimeMedia(runtimeObject.media) : void 0;
|
|
66
127
|
const bootstrap = Result.getOrThrow(Schema.decodeResult(StudioBootstrap)({
|
|
67
128
|
basePath: "/",
|
|
68
129
|
documents: compiled.documents,
|
|
69
130
|
media: {
|
|
70
|
-
enabled:
|
|
71
|
-
maxUploadBytes:
|
|
131
|
+
enabled: runtimeMedia !== void 0,
|
|
132
|
+
maxUploadBytes: authoredMedia?.maxUploadBytes ?? DEFAULT_MEDIA_MAX_UPLOAD_BYTES
|
|
72
133
|
},
|
|
73
|
-
seo:
|
|
134
|
+
seo: compiled.seo ?? makeDefaultSeoOptions(runtime.baseUrl),
|
|
74
135
|
version: "1"
|
|
75
136
|
}));
|
|
76
137
|
return {
|
|
77
138
|
formHandlers: Object.fromEntries(Object.entries(authored.forms ?? {}).map(([name, form]) => [name, form.onSubmit])),
|
|
78
139
|
authoring,
|
|
79
|
-
baseUrl:
|
|
140
|
+
baseUrl: runtime.baseUrl,
|
|
80
141
|
bootstrap,
|
|
81
142
|
cleanup: {
|
|
82
|
-
enabled:
|
|
143
|
+
enabled: compiled.installation.cleanup !== false,
|
|
83
144
|
initialDelayMillis: cleanup?.initialDelayMillis ?? DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS,
|
|
84
145
|
intervalMillis: cleanup?.intervalMillis ?? DEFAULT_CLEANUP_INTERVAL_MILLIS
|
|
85
146
|
},
|
|
86
|
-
|
|
147
|
+
database: {
|
|
148
|
+
schema: compiled.installation.database.schema,
|
|
149
|
+
url: runtime.databaseUrl
|
|
150
|
+
},
|
|
87
151
|
documentModel: compiled.documentModel,
|
|
88
|
-
initializationToken:
|
|
89
|
-
...
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
152
|
+
initializationToken: runtime.initializationToken,
|
|
153
|
+
...runtimeMedia && authoredMedia ? { media: {
|
|
154
|
+
...runtimeMedia,
|
|
155
|
+
credentials: runtimeMedia.accessKeyId && runtimeMedia.secretAccessKey ? {
|
|
156
|
+
accessKeyId: runtimeMedia.accessKeyId,
|
|
157
|
+
secretAccessKey: runtimeMedia.secretAccessKey,
|
|
158
|
+
...runtimeMedia.sessionToken ? { sessionToken: runtimeMedia.sessionToken } : void 0
|
|
159
|
+
} : void 0,
|
|
160
|
+
forcePathStyle: runtimeMedia.forcePathStyle ?? false,
|
|
161
|
+
prefix: authoredMedia.prefix,
|
|
162
|
+
provisionBucket: runtimeMedia.provisionBucket ?? false,
|
|
163
|
+
publicBaseUrl: `${runtimeMedia.publicBaseUrl.replace(/\/+$/gu, "")}/${authoredMedia.prefix.replace(/\/+$/gu, "")}`
|
|
164
|
+
} } : void 0,
|
|
165
|
+
secret: runtime.secret
|
|
96
166
|
};
|
|
97
167
|
}
|
|
168
|
+
function decodeRuntimeMedia(input) {
|
|
169
|
+
const raw = Predicate.isObject(input) ? input : {};
|
|
170
|
+
requireRuntimeValue(raw.bucket, "cms.media.bucket", "NUXT_CMS_MEDIA_BUCKET");
|
|
171
|
+
requireRuntimeValue(raw.publicBaseUrl, "cms.media.publicBaseUrl", "NUXT_CMS_MEDIA_PUBLIC_BASE_URL");
|
|
172
|
+
requireRuntimeValue(raw.region, "cms.media.region", "NUXT_CMS_MEDIA_REGION");
|
|
173
|
+
const optionalString = (value) => Schema.is(Schema.NonEmptyString)(value) ? value : void 0;
|
|
174
|
+
const accessKeyId = optionalString(raw.accessKeyId);
|
|
175
|
+
const endpoint = optionalString(raw.endpoint);
|
|
176
|
+
const secretAccessKey = optionalString(raw.secretAccessKey);
|
|
177
|
+
const sessionToken = optionalString(raw.sessionToken);
|
|
178
|
+
const normalized = Object.assign({
|
|
179
|
+
bucket: raw.bucket,
|
|
180
|
+
publicBaseUrl: raw.publicBaseUrl,
|
|
181
|
+
region: raw.region
|
|
182
|
+
}, accessKeyId ? { accessKeyId } : void 0, endpoint ? { endpoint } : void 0, Schema.is(Schema.Boolean)(raw.forcePathStyle) ? { forcePathStyle: raw.forcePathStyle } : void 0, Schema.is(Schema.Boolean)(raw.provisionBucket) ? { provisionBucket: raw.provisionBucket } : void 0, secretAccessKey ? { secretAccessKey } : void 0, sessionToken ? { sessionToken } : void 0);
|
|
183
|
+
const result = Schema.decodeUnknownResult(RuntimeMediaConfiguration)(normalized);
|
|
184
|
+
if (Result.isFailure(result)) throw new Error(`Invalid CMS runtime media configuration: ${String(result.failure)}`);
|
|
185
|
+
const decoded = result.success;
|
|
186
|
+
if (decoded.accessKeyId === void 0 !== (decoded.secretAccessKey === void 0)) throw new Error("Invalid CMS runtime media configuration: accessKeyId and secretAccessKey must be provided together.");
|
|
187
|
+
return decoded;
|
|
188
|
+
}
|
|
189
|
+
function requireRuntimeValue(value, path, environmentVariable) {
|
|
190
|
+
if (!Schema.is(Schema.NonEmptyString)(value)) throw new CmsRuntimeConfigurationMissing({
|
|
191
|
+
environmentVariable,
|
|
192
|
+
message: `Missing ${environmentVariable} for ${path}.`,
|
|
193
|
+
path
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function decodeOrThrow(schema, input, label) {
|
|
197
|
+
const decoded = Schema.decodeUnknownResult(schema)(input);
|
|
198
|
+
if (Result.isFailure(decoded)) throw new Error(`Invalid CMS ${label} configuration: ${String(decoded.failure)}`);
|
|
199
|
+
return decoded.success;
|
|
200
|
+
}
|
|
98
201
|
|
|
99
202
|
//#endregion
|
|
100
|
-
export { compileCmsConfiguration, resolveCmsInstallation };
|
|
203
|
+
export { cmsRuntimeConfigurationDefaults, cmsRuntimeConfigurationFromEnvironment, compileCmsConfiguration, resolveCmsInstallation };
|
|
101
204
|
//# sourceMappingURL=configuration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.js","names":["PreviewOriginSchema"],"sources":["../../../../src/internal/configuration.ts"],"sourcesContent":["import { compileCmsI18n, type CompiledCmsI18n } from './i18n'\nimport type { ExecutableDocumentModel } from '@internal/document/DocumentEngine'\nimport type { AuthoringCatalog, DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { CmsConfiguration } from '../Configuration'\nimport type { NuxtCmsInstallationOptions } from '../runtime/installation'\nimport { PreviewOrigin as PreviewOriginSchema } from '@internal/protocol/Preview'\nimport { StudioBootstrap } from '@internal/protocol/StudioHttp'\nimport { SeoConfiguration } from '@internal/protocol/Seo'\nimport { makeDefaultSeoOptions } from '@internal/server/Seo'\nimport { maxS3SingleCopyBytes } from '@internal/s3/S3MediaObjects'\nimport { Predicate, Result, Schema } from 'effect'\nimport { compileCmsDocumentModel } from './document-model'\nimport { validateFormCapabilities } from './form-capabilities'\n\nconst DEFAULT_CLEANUP_INTERVAL_MILLIS = 24 * 60 * 60_000\n\nconst DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS = 60_000\n\nconst DEFAULT_MEDIA_MAX_UPLOAD_BYTES = 10_000_000\n\nconst optionalString = Schema.optionalKey(Schema.NonEmptyString)\n\nconst InstallationConfiguration = Schema.Struct({\n baseUrl: PreviewOriginSchema,\n cleanup: Schema.optionalKey(\n Schema.Union([\n Schema.Literals([false]),\n Schema.Struct({\n initialDelayMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n intervalMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0))),\n }),\n ]),\n ),\n databaseUrl: Schema.NonEmptyString,\n initializationToken: Schema.NonEmptyString.check(Schema.isMinLength(32)),\n media: Schema.optionalKey(\n Schema.Union([\n Schema.Literals([false]),\n Schema.Struct({\n maxUploadBytes: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: maxS3SingleCopyBytes })),\n ),\n publicBaseUrl: Schema.NonEmptyString,\n storage: Schema.Struct({\n bucket: Schema.NonEmptyString,\n credentials: Schema.optionalKey(\n Schema.Struct({\n accessKeyId: Schema.NonEmptyString,\n secretAccessKey: Schema.NonEmptyString,\n sessionToken: optionalString,\n }),\n ),\n endpoint: optionalString,\n forcePathStyle: Schema.optionalKey(Schema.Boolean),\n provisionBucket: Schema.optionalKey(Schema.Boolean),\n region: Schema.NonEmptyString,\n }),\n }),\n ]),\n ),\n seo: Schema.optionalKey(SeoConfiguration),\n secret: Schema.NonEmptyString.check(Schema.isMinLength(32)),\n})\n\ntype CmsInstallationConfiguration = Schema.Schema.Type<typeof InstallationConfiguration>\n\nexport interface CompiledCmsConfiguration {\n readonly i18n: CompiledCmsI18n\n readonly documents: DocumentConfiguration\n readonly documentModel: ExecutableDocumentModel\n readonly installation: CmsInstallationConfiguration\n}\n\nexport function compileCmsConfiguration(configuration: CmsConfiguration): CompiledCmsConfiguration {\n const decodedConfiguration = Schema.decodeResult(InstallationConfiguration)(configuration)\n\n if (Result.isFailure(decodedConfiguration)) {\n throw new Error(`Invalid CMS configuration: ${String(decodedConfiguration.failure)}`)\n }\n\n for (const [name, form] of Object.entries(configuration.forms ?? {})) {\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(name))\n throw new Error(`Form ${name} needs a kebab-case Vue component name.`)\n validateFormCapabilities(form.definition)\n\n if (!Predicate.isFunction(form.onSubmit)) throw new Error(`Form ${name} needs a server submission handler.`)\n }\n\n const i18n = compileCmsI18n(configuration.i18n)\n const documents = compileCmsDocumentModel(configuration.documents, configuration.i18n)\n\n return {\n i18n,\n documentModel: documents.executable,\n documents: documents.authoring,\n installation: decodedConfiguration.success,\n }\n}\n\nexport function resolveCmsInstallation(\n authored: CmsConfiguration,\n authoring: AuthoringCatalog,\n): NuxtCmsInstallationOptions {\n const compiled = compileCmsConfiguration(authored)\n const configuration = compiled.installation\n const cleanup = configuration.cleanup === false ? undefined : configuration.cleanup\n const media = configuration.media === false ? undefined : configuration.media\n\n const bootstrap = Result.getOrThrow(\n Schema.decodeResult(StudioBootstrap)({\n basePath: '/',\n documents: compiled.documents,\n media: {\n enabled: media !== undefined,\n maxUploadBytes: media?.maxUploadBytes ?? DEFAULT_MEDIA_MAX_UPLOAD_BYTES,\n },\n seo: configuration.seo ?? makeDefaultSeoOptions(configuration.baseUrl),\n version: '1',\n }),\n )\n\n return {\n formHandlers: Object.fromEntries(Object.entries(authored.forms ?? {}).map(([name, form]) => [name, form.onSubmit])),\n authoring,\n baseUrl: configuration.baseUrl,\n bootstrap,\n cleanup: {\n enabled: configuration.cleanup !== false,\n initialDelayMillis: cleanup?.initialDelayMillis ?? DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS,\n intervalMillis: cleanup?.intervalMillis ?? DEFAULT_CLEANUP_INTERVAL_MILLIS,\n },\n databaseUrl: configuration.databaseUrl,\n documentModel: compiled.documentModel,\n initializationToken: configuration.initializationToken,\n ...(media === undefined\n ? undefined\n : {\n media: {\n publicBaseUrl: media.publicBaseUrl,\n ...media.storage,\n forcePathStyle: media.storage.forcePathStyle ?? false,\n provisionBucket: media.storage.provisionBucket ?? false,\n },\n }),\n secret: configuration.secret,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"configuration.js","names":["PreviewOriginSchema"],"sources":["../../../../src/internal/configuration.ts"],"sourcesContent":["import { compileCmsI18n, type CompiledCmsI18n } from './i18n'\nimport type { ExecutableDocumentModel } from '@internal/document/DocumentEngine'\nimport type { AuthoringCatalog, DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { CmsConfiguration, CmsRuntimeConfiguration } from '../Configuration'\nimport type { NuxtCmsInstallationOptions } from '../runtime/installation'\nimport { PreviewOrigin as PreviewOriginSchema } from '@internal/protocol/Preview'\nimport { StudioBootstrap } from '@internal/protocol/StudioHttp'\nimport { SeoConfiguration } from '@internal/protocol/Seo'\nimport { makeDefaultSeoOptions } from '@internal/server/Seo'\nimport { maxS3SingleCopyBytes } from '@internal/s3/S3MediaObjects'\nimport { Config, Effect, Predicate, Redacted, Result, Schema } from 'effect'\nimport { compileCmsDocumentModel } from './document-model'\nimport { validateFormCapabilities } from './form-capabilities'\n\nconst DEFAULT_CLEANUP_INTERVAL_MILLIS = 24 * 60 * 60_000\n\nconst DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS = 60_000\n\nconst DEFAULT_MEDIA_MAX_UPLOAD_BYTES = 10_000_000\n\nconst AuthoredInstallationConfiguration = Schema.Struct({\n cleanup: Schema.optionalKey(\n Schema.Union([\n Schema.Literals([false]),\n Schema.Struct({\n initialDelayMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n intervalMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0))),\n }),\n ]),\n ),\n database: Schema.Struct({\n schema: Schema.NonEmptyString.check(\n Schema.makeFilter((value) => /^[a-z_][a-z0-9_]{0,62}$/u.test(value), {\n expected: 'a lowercase PostgreSQL identifier',\n }),\n ),\n }),\n media: Schema.optionalKey(\n Schema.Union([\n Schema.Literals([false]),\n Schema.Struct({\n maxUploadBytes: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: maxS3SingleCopyBytes })),\n ),\n prefix: Schema.NonEmptyString.check(\n Schema.makeFilter((value) => !value.startsWith('/') && value.endsWith('/') && !value.includes('..'), {\n expected: 'a relative object prefix ending in /',\n }),\n ),\n }),\n ]),\n ),\n})\n\nconst RuntimeConfiguration = Schema.Struct({\n baseUrl: PreviewOriginSchema,\n databaseUrl: Schema.NonEmptyString,\n initializationToken: Schema.NonEmptyString.check(Schema.isMinLength(32)),\n secret: Schema.NonEmptyString.check(Schema.isMinLength(32)),\n})\n\nconst RuntimeMediaConfiguration = Schema.Struct({\n accessKeyId: Schema.optionalKey(Schema.NonEmptyString),\n bucket: Schema.NonEmptyString,\n endpoint: Schema.optionalKey(Schema.NonEmptyString),\n forcePathStyle: Schema.optionalKey(Schema.Boolean),\n provisionBucket: Schema.optionalKey(Schema.Boolean),\n publicBaseUrl: Schema.NonEmptyString,\n region: Schema.NonEmptyString,\n secretAccessKey: Schema.optionalKey(Schema.NonEmptyString),\n sessionToken: Schema.optionalKey(Schema.NonEmptyString),\n})\n\nclass CmsRuntimeConfigurationMissing extends Schema.TaggedError<CmsRuntimeConfigurationMissing>()(\n 'CmsRuntimeConfigurationMissing',\n {\n environmentVariable: Schema.String,\n message: Schema.String,\n path: Schema.String,\n },\n) {}\n\ntype CmsAuthoredInstallationConfiguration = Schema.Schema.Type<typeof AuthoredInstallationConfiguration>\n\nexport interface CompiledCmsConfiguration {\n readonly i18n: CompiledCmsI18n\n readonly documents: DocumentConfiguration\n readonly documentModel: ExecutableDocumentModel\n readonly installation: CmsAuthoredInstallationConfiguration\n readonly seo?: Schema.Schema.Type<typeof SeoConfiguration>\n}\n\nexport function compileCmsConfiguration(configuration: CmsConfiguration): CompiledCmsConfiguration {\n const installation = decodeOrThrow(\n AuthoredInstallationConfiguration,\n configuration.installation,\n 'authored installation',\n )\n\n for (const [name, form] of Object.entries(configuration.forms ?? {})) {\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(name))\n throw new Error(`Form ${name} needs a kebab-case Vue component name.`)\n validateFormCapabilities(form.definition)\n\n if (!Predicate.isFunction(form.onSubmit)) throw new Error(`Form ${name} needs a server submission handler.`)\n }\n\n const i18n = compileCmsI18n(configuration.i18n)\n const documents = compileCmsDocumentModel(configuration.documents, configuration.i18n)\n const seo = configuration.seo === undefined ? undefined : decodeOrThrow(SeoConfiguration, configuration.seo, 'SEO')\n\n return {\n i18n,\n documentModel: documents.executable,\n documents: documents.authoring,\n installation,\n ...(seo === undefined ? undefined : { seo }),\n }\n}\n\n/** Adds the keys Nitro needs in order to apply NUXT_CMS_* runtime environment overrides. */\nexport function cmsRuntimeConfigurationDefaults(\n authored: CmsConfiguration,\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Nuxt runtime config is an external input parsed field by field here.\n input?: unknown,\n): CmsRuntimeConfiguration {\n const configured = Predicate.isObject(input) ? input : {}\n const mediaEnabled = authored.installation.media !== false && authored.installation.media !== undefined\n const configuredMedia = Predicate.isObject(configured.media) ? configured.media : undefined\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Each external field is narrowed immediately.\n const string = (value: unknown) => (Schema.is(Schema.String)(value) ? value : '')\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Each external field is narrowed immediately.\n const boolean = (value: unknown) => (Schema.is(Schema.Boolean)(value) ? value : false)\n\n return {\n baseUrl: string(configured.baseUrl),\n databaseUrl: string(configured.databaseUrl),\n initializationToken: string(configured.initializationToken),\n media: mediaEnabled\n ? configured.media === false\n ? false\n : {\n accessKeyId: string(configuredMedia?.accessKeyId),\n bucket: string(configuredMedia?.bucket),\n endpoint: string(configuredMedia?.endpoint),\n forcePathStyle: boolean(configuredMedia?.forcePathStyle),\n provisionBucket: boolean(configuredMedia?.provisionBucket),\n publicBaseUrl: string(configuredMedia?.publicBaseUrl),\n region: string(configuredMedia?.region),\n secretAccessKey: string(configuredMedia?.secretAccessKey),\n sessionToken: string(configuredMedia?.sessionToken),\n }\n : false,\n secret: string(configured.secret),\n }\n}\n\n/** Reads the same NUXT_CMS_* values that Nitro applies to runtimeConfig at process startup. */\nexport const cmsRuntimeConfigurationFromEnvironment = Effect.fn('CmsConfiguration.runtimeFromEnvironment')(function* (\n defaults: CmsRuntimeConfiguration,\n) {\n const string = (name: string, fallback: string) => Config.String(name).pipe(Config.withDefault(fallback))\n\n const secret = (name: string, fallback: string) =>\n Config.Redacted(name).pipe(Config.withDefault(Redacted.make(fallback)), Effect.map(Redacted.value))\n\n return {\n baseUrl: yield* string('NUXT_CMS_BASE_URL', defaults.baseUrl),\n databaseUrl: yield* string('NUXT_CMS_DATABASE_URL', defaults.databaseUrl),\n initializationToken: yield* secret('NUXT_CMS_INITIALIZATION_TOKEN', defaults.initializationToken),\n media:\n defaults.media === false || defaults.media === undefined\n ? false\n : {\n accessKeyId: yield* string('NUXT_CMS_MEDIA_ACCESS_KEY_ID', defaults.media.accessKeyId ?? ''),\n bucket: yield* string('NUXT_CMS_MEDIA_BUCKET', defaults.media.bucket),\n endpoint: yield* string('NUXT_CMS_MEDIA_ENDPOINT', defaults.media.endpoint ?? ''),\n forcePathStyle: yield* Config.Boolean('NUXT_CMS_MEDIA_FORCE_PATH_STYLE').pipe(\n Config.withDefault(defaults.media.forcePathStyle ?? false),\n ),\n provisionBucket: yield* Config.Boolean('NUXT_CMS_MEDIA_PROVISION_BUCKET').pipe(\n Config.withDefault(defaults.media.provisionBucket ?? false),\n ),\n publicBaseUrl: yield* string('NUXT_CMS_MEDIA_PUBLIC_BASE_URL', defaults.media.publicBaseUrl),\n region: yield* string('NUXT_CMS_MEDIA_REGION', defaults.media.region),\n secretAccessKey: yield* secret('NUXT_CMS_MEDIA_SECRET_ACCESS_KEY', defaults.media.secretAccessKey ?? ''),\n sessionToken: yield* secret('NUXT_CMS_MEDIA_SESSION_TOKEN', defaults.media.sessionToken ?? ''),\n },\n secret: yield* secret('NUXT_CMS_SECRET', defaults.secret),\n } satisfies CmsRuntimeConfiguration\n})\n\nexport function resolveCmsInstallation(\n authored: CmsConfiguration,\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Shared Nitro/CLI boundary validates this value before resource acquisition.\n runtimeInput: unknown,\n authoring: AuthoringCatalog,\n): NuxtCmsInstallationOptions {\n const compiled = compileCmsConfiguration(authored)\n const runtimeObject = Predicate.isObject(runtimeInput) ? runtimeInput : {}\n requireRuntimeValue(runtimeObject.baseUrl, 'cms.baseUrl', 'NUXT_CMS_BASE_URL')\n requireRuntimeValue(runtimeObject.databaseUrl, 'cms.databaseUrl', 'NUXT_CMS_DATABASE_URL')\n requireRuntimeValue(runtimeObject.initializationToken, 'cms.initializationToken', 'NUXT_CMS_INITIALIZATION_TOKEN')\n requireRuntimeValue(runtimeObject.secret, 'cms.secret', 'NUXT_CMS_SECRET')\n const runtimeResult = Schema.decodeUnknownResult(RuntimeConfiguration)(runtimeInput)\n\n if (Result.isFailure(runtimeResult))\n throw new Error(`Invalid CMS runtime installation configuration: ${String(runtimeResult.failure)}`)\n const runtime = runtimeResult.success\n const cleanup = compiled.installation.cleanup === false ? undefined : compiled.installation.cleanup\n const authoredMedia = compiled.installation.media === false ? undefined : compiled.installation.media\n const runtimeMedia = authoredMedia ? decodeRuntimeMedia(runtimeObject.media) : undefined\n\n const bootstrap = Result.getOrThrow(\n Schema.decodeResult(StudioBootstrap)({\n basePath: '/',\n documents: compiled.documents,\n media: {\n enabled: runtimeMedia !== undefined,\n maxUploadBytes: authoredMedia?.maxUploadBytes ?? DEFAULT_MEDIA_MAX_UPLOAD_BYTES,\n },\n seo: compiled.seo ?? makeDefaultSeoOptions(runtime.baseUrl),\n version: '1',\n }),\n )\n\n return {\n formHandlers: Object.fromEntries(Object.entries(authored.forms ?? {}).map(([name, form]) => [name, form.onSubmit])),\n authoring,\n baseUrl: runtime.baseUrl,\n bootstrap,\n cleanup: {\n enabled: compiled.installation.cleanup !== false,\n initialDelayMillis: cleanup?.initialDelayMillis ?? DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS,\n intervalMillis: cleanup?.intervalMillis ?? DEFAULT_CLEANUP_INTERVAL_MILLIS,\n },\n database: { schema: compiled.installation.database.schema, url: runtime.databaseUrl },\n documentModel: compiled.documentModel,\n initializationToken: runtime.initializationToken,\n ...(runtimeMedia && authoredMedia\n ? {\n media: {\n ...runtimeMedia,\n credentials:\n runtimeMedia.accessKeyId && runtimeMedia.secretAccessKey\n ? {\n accessKeyId: runtimeMedia.accessKeyId,\n secretAccessKey: runtimeMedia.secretAccessKey,\n ...(runtimeMedia.sessionToken ? { sessionToken: runtimeMedia.sessionToken } : undefined),\n }\n : undefined,\n forcePathStyle: runtimeMedia.forcePathStyle ?? false,\n prefix: authoredMedia.prefix,\n provisionBucket: runtimeMedia.provisionBucket ?? false,\n publicBaseUrl: `${runtimeMedia.publicBaseUrl.replace(/\\/+$/gu, '')}/${authoredMedia.prefix.replace(/\\/+$/gu, '')}`,\n },\n }\n : undefined),\n secret: runtime.secret,\n }\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Runtime media is validated before use.\nfunction decodeRuntimeMedia(input: unknown) {\n const raw = Predicate.isObject(input) ? input : {}\n requireRuntimeValue(raw.bucket, 'cms.media.bucket', 'NUXT_CMS_MEDIA_BUCKET')\n requireRuntimeValue(raw.publicBaseUrl, 'cms.media.publicBaseUrl', 'NUXT_CMS_MEDIA_PUBLIC_BASE_URL')\n requireRuntimeValue(raw.region, 'cms.media.region', 'NUXT_CMS_MEDIA_REGION')\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- Each external field is narrowed immediately.\n const optionalString = (value: unknown) => (Schema.is(Schema.NonEmptyString)(value) ? value : undefined)\n const accessKeyId = optionalString(raw.accessKeyId)\n const endpoint = optionalString(raw.endpoint)\n const secretAccessKey = optionalString(raw.secretAccessKey)\n const sessionToken = optionalString(raw.sessionToken)\n\n const normalized = Object.assign(\n { bucket: raw.bucket, publicBaseUrl: raw.publicBaseUrl, region: raw.region },\n accessKeyId ? { accessKeyId } : undefined,\n endpoint ? { endpoint } : undefined,\n Schema.is(Schema.Boolean)(raw.forcePathStyle) ? { forcePathStyle: raw.forcePathStyle } : undefined,\n Schema.is(Schema.Boolean)(raw.provisionBucket) ? { provisionBucket: raw.provisionBucket } : undefined,\n secretAccessKey ? { secretAccessKey } : undefined,\n sessionToken ? { sessionToken } : undefined,\n )\n\n const result = Schema.decodeUnknownResult(RuntimeMediaConfiguration)(normalized)\n\n if (Result.isFailure(result)) throw new Error(`Invalid CMS runtime media configuration: ${String(result.failure)}`)\n const decoded = result.success\n\n if ((decoded.accessKeyId === undefined) !== (decoded.secretAccessKey === undefined))\n throw new Error(\n 'Invalid CMS runtime media configuration: accessKeyId and secretAccessKey must be provided together.',\n )\n\n return decoded\n}\n\nfunction requireRuntimeValue(\n // oxlint-disable-next-line anti-slop/no-unknown-parameters -- This external field is narrowed immediately to a non-empty string.\n value: unknown,\n path: string,\n environmentVariable: string,\n): void {\n if (!Schema.is(Schema.NonEmptyString)(value))\n throw new CmsRuntimeConfigurationMissing({\n environmentVariable,\n message: `Missing ${environmentVariable} for ${path}.`,\n path,\n })\n}\n\nfunction decodeOrThrow<Decoded, Encoded>(\n schema: Schema.Codec<Decoded, Encoded>,\n input: Encoded,\n label: string,\n): Decoded {\n const decoded = Schema.decodeUnknownResult(schema)(input)\n\n if (Result.isFailure(decoded)) throw new Error(`Invalid CMS ${label} configuration: ${String(decoded.failure)}`)\n\n return decoded.success\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Predicate } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/internal/diagnostics.ts
|
|
4
|
+
function diagnosticFromCause(phase, cause) {
|
|
5
|
+
const chain = causeChain(cause);
|
|
6
|
+
const tagged = [...chain].reverse().find((item) => item._tag)?._tag;
|
|
7
|
+
const message = [...chain].reverse().find((item) => item.message)?.message ?? String(cause);
|
|
8
|
+
const missing = message.match(/Missing (NUXT_CMS_[A-Z0-9_]+)/u)?.[1];
|
|
9
|
+
const resolvedPhase = chain.find((item) => item.phase)?.phase ?? phase;
|
|
10
|
+
return {
|
|
11
|
+
code: tagged ? kebabCase(tagged) : `${resolvedPhase.replaceAll(".", "-")}-failed`,
|
|
12
|
+
details: chain.flatMap((item) => item.stack ? [item.stack] : item.message ? [item.message] : []),
|
|
13
|
+
message,
|
|
14
|
+
phase: resolvedPhase,
|
|
15
|
+
...missing ? { remediation: `Define ${missing} in .env, pass --env-file, or provide it in the process environment.` } : void 0
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function renderDiagnostic(diagnostic, verbose) {
|
|
19
|
+
return [
|
|
20
|
+
`✗ ${diagnostic.phase}`,
|
|
21
|
+
"",
|
|
22
|
+
` ${diagnostic.message}`,
|
|
23
|
+
...diagnostic.remediation ? ["", ` ${diagnostic.remediation}`] : [],
|
|
24
|
+
...verbose && diagnostic.details.length ? ["", ...diagnostic.details.map((detail) => ` ${detail}`)] : []
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
27
|
+
function causeChain(cause) {
|
|
28
|
+
const chain = [];
|
|
29
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30
|
+
let current = cause;
|
|
31
|
+
while (isErrorLike(current) && !visited.has(current) && chain.length < 16) {
|
|
32
|
+
visited.add(current);
|
|
33
|
+
chain.push(current);
|
|
34
|
+
current = current.cause;
|
|
35
|
+
}
|
|
36
|
+
return chain;
|
|
37
|
+
}
|
|
38
|
+
function isErrorLike(value) {
|
|
39
|
+
return Predicate.isObject(value);
|
|
40
|
+
}
|
|
41
|
+
function kebabCase(value) {
|
|
42
|
+
return value.replaceAll(/([a-z0-9])([A-Z])/gu, "$1-$2").replaceAll(/[^a-zA-Z0-9]+/gu, "-").replaceAll(/^-|-$/gu, "").toLocaleLowerCase();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
export { diagnosticFromCause, renderDiagnostic };
|
|
47
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","names":[],"sources":["../../../../src/internal/diagnostics.ts"],"sourcesContent":["import { Predicate } from 'effect'\n\nexport interface CmsDiagnostic {\n readonly code: string\n readonly details: ReadonlyArray<string>\n readonly message: string\n readonly phase: string\n readonly remediation?: string\n}\n\ninterface ErrorLike {\n readonly _tag?: string\n readonly cause?: unknown\n readonly message?: string\n readonly phase?: string\n readonly stack?: string\n}\n\nexport function diagnosticFromCause(phase: string, cause: unknown): CmsDiagnostic {\n const chain = causeChain(cause)\n const tagged = [...chain].reverse().find((item) => item._tag)?._tag\n const message = [...chain].reverse().find((item) => item.message)?.message ?? String(cause)\n const missing = message.match(/Missing (NUXT_CMS_[A-Z0-9_]+)/u)?.[1]\n const resolvedPhase = chain.find((item) => item.phase)?.phase ?? phase\n\n return {\n code: tagged ? kebabCase(tagged) : `${resolvedPhase.replaceAll('.', '-')}-failed`,\n details: chain.flatMap((item) => (item.stack ? [item.stack] : item.message ? [item.message] : [])),\n message,\n phase: resolvedPhase,\n ...(missing\n ? { remediation: `Define ${missing} in .env, pass --env-file, or provide it in the process environment.` }\n : undefined),\n }\n}\n\nexport function renderDiagnostic(diagnostic: CmsDiagnostic, verbose: boolean): string {\n return [\n `✗ ${diagnostic.phase}`,\n '',\n ` ${diagnostic.message}`,\n ...(diagnostic.remediation ? ['', ` ${diagnostic.remediation}`] : []),\n ...(verbose && diagnostic.details.length ? ['', ...diagnostic.details.map((detail) => ` ${detail}`)] : []),\n ].join('\\n')\n}\n\nfunction causeChain(cause: unknown): ErrorLike[] {\n const chain: ErrorLike[] = []\n const visited = new Set<unknown>()\n let current: unknown = cause\n\n while (isErrorLike(current) && !visited.has(current) && chain.length < 16) {\n visited.add(current)\n chain.push(current)\n current = current.cause\n }\n\n return chain\n}\n\nfunction isErrorLike(value: unknown): value is ErrorLike {\n return Predicate.isObject(value)\n}\n\nfunction kebabCase(value: string): string {\n return value\n .replaceAll(/([a-z0-9])([A-Z])/gu, '$1-$2')\n .replaceAll(/[^a-zA-Z0-9]+/gu, '-')\n .replaceAll(/^-|-$/gu, '')\n .toLocaleLowerCase()\n}\n"],"mappings":";;;AAkBA,SAAgB,oBAAoB,OAAe,OAA+B;CAChF,MAAM,QAAQ,WAAW,KAAK;CAC9B,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,SAAS,KAAK,IAAI,CAAC,EAAE;CAC/D,MAAM,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,SAAS,KAAK,OAAO,CAAC,EAAE,WAAW,OAAO,KAAK;CAC1F,MAAM,UAAU,QAAQ,MAAM,gCAAgC,CAAC,GAAG;CAClE,MAAM,gBAAgB,MAAM,MAAM,SAAS,KAAK,KAAK,CAAC,EAAE,SAAS;CAEjE,OAAO;EACL,MAAM,SAAS,UAAU,MAAM,IAAI,GAAG,cAAc,WAAW,KAAK,GAAG,EAAE;EACzE,SAAS,MAAM,SAAS,SAAU,KAAK,QAAQ,CAAC,KAAK,KAAK,IAAI,KAAK,UAAU,CAAC,KAAK,OAAO,IAAI,CAAC,CAAE;EACjG;EACA,OAAO;EACP,GAAI,UACA,EAAE,aAAa,UAAU,QAAQ,sEAAsE,IACvG;CACN;AACF;AAEA,SAAgB,iBAAiB,YAA2B,SAA0B;CACpF,OAAO;EACL,KAAK,WAAW;EAChB;EACA,KAAK,WAAW;EAChB,GAAI,WAAW,cAAc,CAAC,IAAI,KAAK,WAAW,aAAa,IAAI,CAAC;EACpE,GAAI,WAAW,WAAW,QAAQ,SAAS,CAAC,IAAI,GAAG,WAAW,QAAQ,KAAK,WAAW,KAAK,QAAQ,CAAC,IAAI,CAAC;CAC3G,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,WAAW,OAA6B;CAC/C,MAAM,QAAqB,CAAC;CAC5B,MAAM,0BAAU,IAAI,IAAa;CACjC,IAAI,UAAmB;CAEvB,OAAO,YAAY,OAAO,KAAK,CAAC,QAAQ,IAAI,OAAO,KAAK,MAAM,SAAS,IAAI;EACzE,QAAQ,IAAI,OAAO;EACnB,MAAM,KAAK,OAAO;EAClB,UAAU,QAAQ;CACpB;CAEA,OAAO;AACT;AAEA,SAAS,YAAY,OAAoC;CACvD,OAAO,UAAU,SAAS,KAAK;AACjC;AAEA,SAAS,UAAU,OAAuB;CACxC,OAAO,MACJ,WAAW,uBAAuB,OAAO,CAAC,CAC1C,WAAW,mBAAmB,GAAG,CAAC,CAClC,WAAW,WAAW,EAAE,CAAC,CACzB,kBAAkB;AACvB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FIELD_INPUT_METADATA } from "./field-metadata.js";
|
|
2
|
-
import { r as DocumentConfiguration } from "../Configuration-
|
|
3
|
-
import { t as createDocumentEngine } from "../DocumentEngine-
|
|
2
|
+
import { r as DocumentConfiguration } from "../Configuration-BU-UyGoH.js";
|
|
3
|
+
import { t as createDocumentEngine } from "../DocumentEngine-ClhFXW9M.js";
|
|
4
4
|
import { Effect, Predicate, Result, Schema } from "effect";
|
|
5
5
|
|
|
6
6
|
//#region src/internal/document-model.ts
|