@phtngyn/cms 0.1.0-beta.0

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 (120) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +90 -0
  3. package/dist/studio/assets/ActivityEntryRow-D--fRvWI.js +1 -0
  4. package/dist/studio/assets/ActivityView-D-XBBUHb.js +1 -0
  5. package/dist/studio/assets/CreateDocumentDialog-CH8UH1QM.js +1 -0
  6. package/dist/studio/assets/DocumentsView-CxRpmAxt.js +34 -0
  7. package/dist/studio/assets/DropdownMenu-BSb1l7fr.js +1 -0
  8. package/dist/studio/assets/Input-DVao38h7.js +3 -0
  9. package/dist/studio/assets/MediaView-BHrPIjxB.js +1 -0
  10. package/dist/studio/assets/Modal-VNrXGa5C.js +1 -0
  11. package/dist/studio/assets/OverviewView-DfP6-mLZ.js +1 -0
  12. package/dist/studio/assets/Select-BJZIs9sY.js +1 -0
  13. package/dist/studio/assets/SettingsView-CerHe-ua.js +1 -0
  14. package/dist/studio/assets/Skeleton-CWJNi3nS.js +1 -0
  15. package/dist/studio/assets/StudioPageHeader-DP9HDAF2.js +1 -0
  16. package/dist/studio/assets/UsersView-cP3REkH2.js +1 -0
  17. package/dist/studio/assets/collaboration-BLnCzfvV.js +4 -0
  18. package/dist/studio/assets/context-dY4fNbn3.js +1 -0
  19. package/dist/studio/assets/editor-CE07wW83.js +137 -0
  20. package/dist/studio/assets/gateway-BAyQgCse.js +10 -0
  21. package/dist/studio/assets/index-CjoaPLhZ.js +28 -0
  22. package/dist/studio/assets/index-s2rPqCmP.css +2 -0
  23. package/dist/studio/assets/render-BkxbK2St.js +83 -0
  24. package/dist/studio/assets/rolldown-runtime-DK3Fl9T5.js +1 -0
  25. package/dist/studio/assets/useMediaLibrary-D7qR7aBf.js +1 -0
  26. package/dist/studio/index.html +76 -0
  27. package/package.json +75 -0
  28. package/src/Authoring.d.ts +46 -0
  29. package/src/Authoring.js +1 -0
  30. package/src/AuthoringSchema-BQ5kbhVB.js +926 -0
  31. package/src/AuthoringSchema-BQ5kbhVB.js.map +1 -0
  32. package/src/Configuration-BGYFD2N1.js +150 -0
  33. package/src/Configuration-BGYFD2N1.js.map +1 -0
  34. package/src/Configuration.d.ts +44 -0
  35. package/src/Configuration.js +9 -0
  36. package/src/Configuration.js.map +1 -0
  37. package/src/DocumentEngine-Da0kWotL.js +851 -0
  38. package/src/DocumentEngine-Da0kWotL.js.map +1 -0
  39. package/src/DocumentModel.d.ts +30 -0
  40. package/src/DocumentModel.js +15 -0
  41. package/src/DocumentModel.js.map +1 -0
  42. package/src/HttpPaths-86qLGB90.js +15 -0
  43. package/src/HttpPaths-86qLGB90.js.map +1 -0
  44. package/src/Module.d.ts +12 -0
  45. package/src/Module.js +167 -0
  46. package/src/Module.js.map +1 -0
  47. package/src/StudioHttp-BTLLooh0.js +916 -0
  48. package/src/StudioHttp-BTLLooh0.js.map +1 -0
  49. package/src/connection-ZGtL54qY.js +94 -0
  50. package/src/connection-ZGtL54qY.js.map +1 -0
  51. package/src/installation-BNKaVjni.js +9128 -0
  52. package/src/installation-BNKaVjni.js.map +1 -0
  53. package/src/internal/authoring-compiler.js +120 -0
  54. package/src/internal/authoring-compiler.js.map +1 -0
  55. package/src/internal/authoring-metadata.js +163 -0
  56. package/src/internal/authoring-metadata.js.map +1 -0
  57. package/src/internal/cms-config.js +46 -0
  58. package/src/internal/cms-config.js.map +1 -0
  59. package/src/internal/component-metadata.js +37 -0
  60. package/src/internal/component-metadata.js.map +1 -0
  61. package/src/internal/configuration.js +93 -0
  62. package/src/internal/configuration.js.map +1 -0
  63. package/src/internal/document-model.js +236 -0
  64. package/src/internal/document-model.js.map +1 -0
  65. package/src/internal/field-metadata.js +6 -0
  66. package/src/internal/field-metadata.js.map +1 -0
  67. package/src/metadata-Czvi3E4K.js +190 -0
  68. package/src/metadata-Czvi3E4K.js.map +1 -0
  69. package/src/models-Citx8jBi.js +306 -0
  70. package/src/models-Citx8jBi.js.map +1 -0
  71. package/src/models-DS5ClMsH.js +153 -0
  72. package/src/models-DS5ClMsH.js.map +1 -0
  73. package/src/runtime/api.js +9 -0
  74. package/src/runtime/api.js.map +1 -0
  75. package/src/runtime/collaboration.js +40 -0
  76. package/src/runtime/collaboration.js.map +1 -0
  77. package/src/runtime/delivery/DocumentField.js +23 -0
  78. package/src/runtime/delivery/DocumentField.js.map +1 -0
  79. package/src/runtime/delivery/DocumentRenderer.js +51 -0
  80. package/src/runtime/delivery/DocumentRenderer.js.map +1 -0
  81. package/src/runtime/delivery/DocumentScope.js +41 -0
  82. package/src/runtime/delivery/DocumentScope.js.map +1 -0
  83. package/src/runtime/delivery/document-page.js +23 -0
  84. package/src/runtime/delivery/document-page.js.map +1 -0
  85. package/src/runtime/delivery/document.js +25 -0
  86. package/src/runtime/delivery/document.js.map +1 -0
  87. package/src/runtime/delivery/preview.d.ts +11 -0
  88. package/src/runtime/delivery/preview.js +6 -0
  89. package/src/runtime/delivery/preview.js.map +1 -0
  90. package/src/runtime/delivery/types.d.ts +80 -0
  91. package/src/runtime/delivery/types.js +1 -0
  92. package/src/runtime/delivery/useDocument.d.ts +6 -0
  93. package/src/runtime/delivery/useDocument.js +20 -0
  94. package/src/runtime/delivery/useDocument.js.map +1 -0
  95. package/src/runtime/delivery/useDocumentQuery.d.ts +7 -0
  96. package/src/runtime/delivery/useDocumentQuery.js +26 -0
  97. package/src/runtime/delivery/useDocumentQuery.js.map +1 -0
  98. package/src/runtime/installation.js +3 -0
  99. package/src/runtime/plugin.js +32 -0
  100. package/src/runtime/plugin.js.map +1 -0
  101. package/src/runtime/preview/CmsStudioPreviewMarker.js +15 -0
  102. package/src/runtime/preview/CmsStudioPreviewMarker.js.map +1 -0
  103. package/src/runtime/preview/comark-document.js +38 -0
  104. package/src/runtime/preview/comark-document.js.map +1 -0
  105. package/src/runtime/preview/connection.js +3 -0
  106. package/src/runtime/preview/controller.js +247 -0
  107. package/src/runtime/preview/controller.js.map +1 -0
  108. package/src/runtime/preview/plugin.client.js +70 -0
  109. package/src/runtime/preview/plugin.client.js.map +1 -0
  110. package/src/runtime/preview/preview.css +9 -0
  111. package/src/runtime/preview/protocol.d.ts +10 -0
  112. package/src/runtime/preview/protocol.js +11 -0
  113. package/src/runtime/preview/protocol.js.map +1 -0
  114. package/src/runtime/preview/store.js +4 -0
  115. package/src/runtime/preview/targets.js +102 -0
  116. package/src/runtime/preview/targets.js.map +1 -0
  117. package/src/runtime/studio-app.js +13 -0
  118. package/src/runtime/studio-app.js.map +1 -0
  119. package/src/store-Nl4uxEXx.js +221 -0
  120. package/src/store-Nl4uxEXx.js.map +1 -0
@@ -0,0 +1,120 @@
1
+ import { MagicString, babelParse, parse, walkIdentifiers } from "@vue/compiler-sfc";
2
+
3
+ //#region src/internal/authoring-compiler.ts
4
+ const authoringImport = "@phtngyn/cms/Authoring";
5
+ /** Reads static authoring data and erases the macro before Vue compiles the SFC. */
6
+ function compileCmsBlock(source, filename) {
7
+ if (!source.includes(authoringImport)) return void 0;
8
+ const { descriptor, errors } = parse(source, { filename });
9
+ if (errors.length) throw new Error(`${filename}: ${errors.join("\n")}`);
10
+ if (descriptor.script?.content.includes(authoringImport)) {
11
+ if (babelParse(descriptor.script.content, {
12
+ sourceType: "module",
13
+ plugins: ["typescript"]
14
+ }).program.body.some((statement) => statement.type === "ImportDeclaration" && statement.source.value === authoringImport && statement.importKind !== "type" && statement.specifiers.some((specifier) => specifier.type !== "ImportSpecifier" || specifier.importKind !== "type"))) throw new Error(`${filename}: defineCmsBlock requires <script setup lang="ts">.`);
15
+ }
16
+ const setup = descriptor.scriptSetup;
17
+ if (!setup) return void 0;
18
+ const ast = babelParse(setup.content, {
19
+ sourceType: "module",
20
+ plugins: ["typescript"]
21
+ });
22
+ const imports = ast.program.body.filter((statement) => statement.type === "ImportDeclaration" && statement.source.value === authoringImport && statement.importKind !== "type");
23
+ if (!imports.length) return void 0;
24
+ const imported = imports[0];
25
+ if (imported?.type !== "ImportDeclaration") return void 0;
26
+ const specifier = imported.specifiers[0];
27
+ if (imports.length !== 1 || imported.specifiers.length !== 1 || specifier?.type !== "ImportSpecifier" || specifier.importKind === "type" || specifier.imported.type !== "Identifier" || specifier.imported.name !== "defineCmsBlock") throw new Error(`${filename}: use a dedicated named import for defineCmsBlock.`);
28
+ if (setup.lang !== "ts" || setup.attrs.generic) throw new Error(`${filename}: defineCmsBlock requires a non-generic <script setup lang="ts">.`);
29
+ const calls = ast.program.body.filter((statement) => statement.type === "ExpressionStatement" && statement.expression.type === "CallExpression" && statement.expression.callee.type === "Identifier" && statement.expression.callee.name === specifier.local.name);
30
+ const statement = calls[0];
31
+ if (calls.length !== 1 || statement?.type !== "ExpressionStatement" || statement.expression.type !== "CallExpression") throw new Error(`${filename}: defineCmsBlock must be called exactly once as a top-level statement.`);
32
+ const call = statement.expression;
33
+ const argument = call.arguments[0];
34
+ if (call.arguments.length !== 1 || argument?.type !== "ObjectExpression") throw new Error(`${filename}: defineCmsBlock requires one object literal.`);
35
+ const types = call.typeParameters?.type === "TSTypeParameterInstantiation" ? call.typeParameters.params : [];
36
+ if (types.length !== 2) throw new Error(`${filename}: share named Props and Slots types with defineProps and defineSlots.`);
37
+ const names = types.map((type) => {
38
+ if (type.type !== "TSTypeReference" || type.typeName.type !== "Identifier" || type.typeParameters) throw new Error(`${filename}: defineCmsBlock type arguments must be named, non-generic types.`);
39
+ return type.typeName.name;
40
+ });
41
+ const vueCalls = /* @__PURE__ */ new Map();
42
+ walkIdentifiers(ast.program, (identifier, parent, _stack, isReference) => {
43
+ if (!isReference) return;
44
+ if (identifier.name === specifier.local.name && identifier !== call.callee) throw new Error(`${filename}: defineCmsBlock may only be used in its top-level declaration.`);
45
+ if ((identifier.name === "defineProps" || identifier.name === "defineSlots") && parent?.type === "CallExpression" && parent.callee === identifier) vueCalls.set(identifier.name, parent);
46
+ });
47
+ for (const [index, macro] of ["defineProps", "defineSlots"].entries()) {
48
+ const parameters = vueCalls.get(macro)?.typeParameters;
49
+ const type = parameters?.type === "TSTypeParameterInstantiation" ? parameters.params[0] : void 0;
50
+ if (type?.type !== "TSTypeReference" || type.typeName.type !== "Identifier" || type.typeParameters !== void 0 || type.typeName.name !== names[index]) throw new Error(`${filename}: ${macro} must use the same ${names[index]} type as defineCmsBlock.`);
51
+ }
52
+ const declaration = staticValue(argument, filename);
53
+ const code = new MagicString(source);
54
+ for (const node of [imported, statement]) {
55
+ if (node.start === null || node.start === void 0 || node.end === null || node.end === void 0) throw new Error(`${filename}: missing authoring declaration source location.`);
56
+ code.remove(setup.loc.start.offset + node.start, setup.loc.start.offset + node.end);
57
+ }
58
+ return {
59
+ declaration,
60
+ code: code.toString(),
61
+ map: code.generateMap({
62
+ source: filename,
63
+ includeContent: true,
64
+ hires: true
65
+ })
66
+ };
67
+ }
68
+ function staticValue(expression, filename) {
69
+ switch (expression.type) {
70
+ case "StringLiteral":
71
+ case "BooleanLiteral": return expression.value;
72
+ case "NumericLiteral":
73
+ if (Number.isFinite(expression.value)) return expression.value;
74
+ break;
75
+ case "NullLiteral": return null;
76
+ case "UnaryExpression":
77
+ if (expression.operator === "-" && expression.argument.type === "NumericLiteral" && Number.isFinite(expression.argument.value)) return -expression.argument.value;
78
+ break;
79
+ case "ArrayExpression": return expression.elements.map((element) => {
80
+ if (!element || element.type === "SpreadElement") throw new Error(`${filename}: authoring arrays require literal entries.`);
81
+ return staticValue(element, filename);
82
+ });
83
+ case "ObjectExpression": {
84
+ const entries = expression.properties.map((property) => {
85
+ if (property.type !== "ObjectProperty" || property.computed || property.shorthand || property.key.type !== "Identifier" && property.key.type !== "StringLiteral") throw new Error(`${filename}: authoring objects require literal named properties; spreads and methods are unsupported.`);
86
+ return [property.key.type === "Identifier" ? property.key.name : property.key.value, staticValue(property.value, filename)];
87
+ });
88
+ if (new Set(entries.map(([key]) => key)).size !== entries.length) throw new Error(`${filename}: duplicate authoring property.`);
89
+ return Object.fromEntries(entries);
90
+ }
91
+ }
92
+ throw new Error(`${filename}: authoring metadata must contain only JSON literals; ${expression.type} is unsupported.`);
93
+ }
94
+ /** Reads Vue's printed default expression without evaluating application code. */
95
+ function readAuthoringDefault(source, filename) {
96
+ const expression = babelParse(`(${source})`, {
97
+ sourceType: "module",
98
+ plugins: ["typescript"]
99
+ }).program.body[0];
100
+ if (expression?.type !== "ExpressionStatement") throw new Error(`${filename}: expected a literal Vue default.`);
101
+ return staticValue(expression.expression, filename);
102
+ }
103
+ function cmsAuthoringPlugin() {
104
+ return {
105
+ name: "cms:authoring",
106
+ enforce: "pre",
107
+ transform(source, id) {
108
+ if (!id.endsWith(".vue")) return void 0;
109
+ const compiled = compileCmsBlock(source, id);
110
+ return compiled ? {
111
+ code: compiled.code,
112
+ map: compiled.map
113
+ } : void 0;
114
+ }
115
+ };
116
+ }
117
+
118
+ //#endregion
119
+ export { cmsAuthoringPlugin, compileCmsBlock, readAuthoringDefault };
120
+ //# sourceMappingURL=authoring-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-compiler.js","names":[],"sources":["../../../../src/internal/authoring-compiler.ts"],"sourcesContent":["import { babelParse, MagicString, parse, walkIdentifiers } from '@vue/compiler-sfc'\nimport type { Schema } from 'effect'\n\nconst authoringImport = '@phtngyn/cms/Authoring'\ntype Statement = ReturnType<typeof babelParse>['program']['body'][number]\ntype Expression = Extract<Statement, { type: 'ExpressionStatement' }>['expression']\ntype Call = Extract<Expression, { type: 'CallExpression' }>\n\n/** Reads static authoring data and erases the macro before Vue compiles the SFC. */\nexport function compileCmsBlock(source: string, filename: string) {\n if (!source.includes(authoringImport)) return undefined\n const { descriptor, errors } = parse(source, { filename })\n if (errors.length) throw new Error(`${filename}: ${errors.join('\\n')}`)\n if (descriptor.script?.content.includes(authoringImport)) {\n const script = babelParse(descriptor.script.content, { sourceType: 'module', plugins: ['typescript'] })\n if (\n script.program.body.some(\n (statement) =>\n statement.type === 'ImportDeclaration' &&\n statement.source.value === authoringImport &&\n statement.importKind !== 'type' &&\n statement.specifiers.some(\n (specifier) => specifier.type !== 'ImportSpecifier' || specifier.importKind !== 'type',\n ),\n )\n )\n throw new Error(`${filename}: defineCmsBlock requires <script setup lang=\"ts\">.`)\n }\n const setup = descriptor.scriptSetup\n if (!setup) return undefined\n const ast = babelParse(setup.content, { sourceType: 'module', plugins: ['typescript'] })\n const imports = ast.program.body.filter(\n (statement) =>\n statement.type === 'ImportDeclaration' &&\n statement.source.value === authoringImport &&\n statement.importKind !== 'type',\n )\n if (!imports.length) return undefined\n const imported = imports[0]\n if (imported?.type !== 'ImportDeclaration') return undefined\n const specifier = imported.specifiers[0]\n if (\n imports.length !== 1 ||\n imported.specifiers.length !== 1 ||\n specifier?.type !== 'ImportSpecifier' ||\n specifier.importKind === 'type' ||\n specifier.imported.type !== 'Identifier' ||\n specifier.imported.name !== 'defineCmsBlock'\n ) {\n throw new Error(`${filename}: use a dedicated named import for defineCmsBlock.`)\n }\n if (setup.lang !== 'ts' || setup.attrs.generic) {\n throw new Error(`${filename}: defineCmsBlock requires a non-generic <script setup lang=\"ts\">.`)\n }\n const calls = ast.program.body.filter(\n (statement) =>\n statement.type === 'ExpressionStatement' &&\n statement.expression.type === 'CallExpression' &&\n statement.expression.callee.type === 'Identifier' &&\n statement.expression.callee.name === specifier.local.name,\n )\n const statement = calls[0]\n if (\n calls.length !== 1 ||\n statement?.type !== 'ExpressionStatement' ||\n statement.expression.type !== 'CallExpression'\n ) {\n throw new Error(`${filename}: defineCmsBlock must be called exactly once as a top-level statement.`)\n }\n const call = statement.expression\n const argument = call.arguments[0]\n if (call.arguments.length !== 1 || argument?.type !== 'ObjectExpression') {\n throw new Error(`${filename}: defineCmsBlock requires one object literal.`)\n }\n const types = call.typeParameters?.type === 'TSTypeParameterInstantiation' ? call.typeParameters.params : []\n if (types.length !== 2)\n throw new Error(`${filename}: share named Props and Slots types with defineProps and defineSlots.`)\n const names = types.map((type) => {\n if (type.type !== 'TSTypeReference' || type.typeName.type !== 'Identifier' || type.typeParameters) {\n throw new Error(`${filename}: defineCmsBlock type arguments must be named, non-generic types.`)\n }\n return type.typeName.name\n })\n const vueCalls = new Map<string, Call>()\n walkIdentifiers(ast.program, (identifier, parent, _stack, isReference) => {\n if (!isReference) return\n if (identifier.name === specifier.local.name && identifier !== call.callee) {\n throw new Error(`${filename}: defineCmsBlock may only be used in its top-level declaration.`)\n }\n if (\n (identifier.name === 'defineProps' || identifier.name === 'defineSlots') &&\n parent?.type === 'CallExpression' &&\n parent.callee === identifier\n ) {\n vueCalls.set(identifier.name, parent)\n }\n })\n for (const [index, macro] of ['defineProps', 'defineSlots'].entries()) {\n const vueCall = vueCalls.get(macro)\n const parameters = vueCall?.typeParameters\n const type = parameters?.type === 'TSTypeParameterInstantiation' ? parameters.params[0] : undefined\n if (\n type?.type !== 'TSTypeReference' ||\n type.typeName.type !== 'Identifier' ||\n type.typeParameters !== undefined ||\n type.typeName.name !== names[index]\n ) {\n throw new Error(`${filename}: ${macro} must use the same ${names[index]} type as defineCmsBlock.`)\n }\n }\n const declaration = staticValue(argument, filename)\n const code = new MagicString(source)\n for (const node of [imported, statement]) {\n if (node.start === null || node.start === undefined || node.end === null || node.end === undefined) {\n throw new Error(`${filename}: missing authoring declaration source location.`)\n }\n code.remove(setup.loc.start.offset + node.start, setup.loc.start.offset + node.end)\n }\n return {\n declaration,\n code: code.toString(),\n map: code.generateMap({ source: filename, includeContent: true, hires: true }),\n }\n}\n\nfunction staticValue(expression: Parameters<typeof walkIdentifiers>[0], filename: string): Schema.Json {\n switch (expression.type) {\n case 'StringLiteral':\n case 'BooleanLiteral':\n return expression.value\n case 'NumericLiteral':\n if (Number.isFinite(expression.value)) return expression.value\n break\n case 'NullLiteral':\n return null\n case 'UnaryExpression':\n if (\n expression.operator === '-' &&\n expression.argument.type === 'NumericLiteral' &&\n Number.isFinite(expression.argument.value)\n ) {\n return -expression.argument.value\n }\n break\n case 'ArrayExpression':\n return expression.elements.map((element) => {\n if (!element || element.type === 'SpreadElement')\n throw new Error(`${filename}: authoring arrays require literal entries.`)\n return staticValue(element, filename)\n })\n case 'ObjectExpression': {\n const entries = expression.properties.map((property): [string, Schema.Json] => {\n if (\n property.type !== 'ObjectProperty' ||\n property.computed ||\n property.shorthand ||\n (property.key.type !== 'Identifier' && property.key.type !== 'StringLiteral')\n ) {\n throw new Error(\n `${filename}: authoring objects require literal named properties; spreads and methods are unsupported.`,\n )\n }\n return [\n property.key.type === 'Identifier' ? property.key.name : property.key.value,\n staticValue(property.value, filename),\n ]\n })\n if (new Set(entries.map(([key]) => key)).size !== entries.length)\n throw new Error(`${filename}: duplicate authoring property.`)\n return Object.fromEntries(entries)\n }\n }\n throw new Error(`${filename}: authoring metadata must contain only JSON literals; ${expression.type} is unsupported.`)\n}\n\n/** Reads Vue's printed default expression without evaluating application code. */\nexport function readAuthoringDefault(source: string, filename: string): Schema.Json {\n const expression = babelParse(`(${source})`, { sourceType: 'module', plugins: ['typescript'] }).program.body[0]\n if (expression?.type !== 'ExpressionStatement') throw new Error(`${filename}: expected a literal Vue default.`)\n return staticValue(expression.expression, filename)\n}\n\nexport function cmsAuthoringPlugin() {\n return {\n name: 'cms:authoring',\n enforce: 'pre' as const,\n transform(source: string, id: string) {\n if (!id.endsWith('.vue')) return undefined\n const compiled = compileCmsBlock(source, id)\n return compiled ? { code: compiled.code, map: compiled.map } : undefined\n },\n }\n}\n"],"mappings":";;;AAGA,MAAM,kBAAkB;;AAMxB,SAAgB,gBAAgB,QAAgB,UAAkB;CAChE,IAAI,CAAC,OAAO,SAAS,eAAe,GAAG,OAAO;CAC9C,MAAM,EAAE,YAAY,WAAW,MAAM,QAAQ,EAAE,SAAS,CAAC;CACzD,IAAI,OAAO,QAAQ,MAAM,IAAI,MAAM,GAAG,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG;CACtE,IAAI,WAAW,QAAQ,QAAQ,SAAS,eAAe,GAErD;MADe,WAAW,WAAW,OAAO,SAAS;GAAE,YAAY;GAAU,SAAS,CAAC,YAAY;EAAE,CAE9F,CAAC,CAAC,QAAQ,KAAK,MACjB,cACC,UAAU,SAAS,uBACnB,UAAU,OAAO,UAAU,mBAC3B,UAAU,eAAe,UACzB,UAAU,WAAW,MAClB,cAAc,UAAU,SAAS,qBAAqB,UAAU,eAAe,MAClF,CACJ,GAEA,MAAM,IAAI,MAAM,GAAG,SAAS,oDAAoD;;CAEpF,MAAM,QAAQ,WAAW;CACzB,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,MAAM,WAAW,MAAM,SAAS;EAAE,YAAY;EAAU,SAAS,CAAC,YAAY;CAAE,CAAC;CACvF,MAAM,UAAU,IAAI,QAAQ,KAAK,QAC9B,cACC,UAAU,SAAS,uBACnB,UAAU,OAAO,UAAU,mBAC3B,UAAU,eAAe,MAC7B;CACA,IAAI,CAAC,QAAQ,QAAQ,OAAO;CAC5B,MAAM,WAAW,QAAQ;CACzB,IAAI,UAAU,SAAS,qBAAqB,OAAO;CACnD,MAAM,YAAY,SAAS,WAAW;CACtC,IACE,QAAQ,WAAW,KACnB,SAAS,WAAW,WAAW,KAC/B,WAAW,SAAS,qBACpB,UAAU,eAAe,UACzB,UAAU,SAAS,SAAS,gBAC5B,UAAU,SAAS,SAAS,kBAE5B,MAAM,IAAI,MAAM,GAAG,SAAS,mDAAmD;CAEjF,IAAI,MAAM,SAAS,QAAQ,MAAM,MAAM,SACrC,MAAM,IAAI,MAAM,GAAG,SAAS,kEAAkE;CAEhG,MAAM,QAAQ,IAAI,QAAQ,KAAK,QAC5B,cACC,UAAU,SAAS,yBACnB,UAAU,WAAW,SAAS,oBAC9B,UAAU,WAAW,OAAO,SAAS,gBACrC,UAAU,WAAW,OAAO,SAAS,UAAU,MAAM,IACzD;CACA,MAAM,YAAY,MAAM;CACxB,IACE,MAAM,WAAW,KACjB,WAAW,SAAS,yBACpB,UAAU,WAAW,SAAS,kBAE9B,MAAM,IAAI,MAAM,GAAG,SAAS,uEAAuE;CAErG,MAAM,OAAO,UAAU;CACvB,MAAM,WAAW,KAAK,UAAU;CAChC,IAAI,KAAK,UAAU,WAAW,KAAK,UAAU,SAAS,oBACpD,MAAM,IAAI,MAAM,GAAG,SAAS,8CAA8C;CAE5E,MAAM,QAAQ,KAAK,gBAAgB,SAAS,iCAAiC,KAAK,eAAe,SAAS,CAAC;CAC3G,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,MAAM,GAAG,SAAS,sEAAsE;CACpG,MAAM,QAAQ,MAAM,KAAK,SAAS;EAChC,IAAI,KAAK,SAAS,qBAAqB,KAAK,SAAS,SAAS,gBAAgB,KAAK,gBACjF,MAAM,IAAI,MAAM,GAAG,SAAS,kEAAkE;EAEhG,OAAO,KAAK,SAAS;CACvB,CAAC;CACD,MAAM,2BAAW,IAAI,IAAkB;CACvC,gBAAgB,IAAI,UAAU,YAAY,QAAQ,QAAQ,gBAAgB;EACxE,IAAI,CAAC,aAAa;EAClB,IAAI,WAAW,SAAS,UAAU,MAAM,QAAQ,eAAe,KAAK,QAClE,MAAM,IAAI,MAAM,GAAG,SAAS,gEAAgE;EAE9F,KACG,WAAW,SAAS,iBAAiB,WAAW,SAAS,kBAC1D,QAAQ,SAAS,oBACjB,OAAO,WAAW,YAElB,SAAS,IAAI,WAAW,MAAM,MAAM;CAExC,CAAC;CACD,KAAK,MAAM,CAAC,OAAO,UAAU,CAAC,eAAe,aAAa,CAAC,CAAC,QAAQ,GAAG;EAErE,MAAM,aADU,SAAS,IAAI,KACJ,CAAC,EAAE;EAC5B,MAAM,OAAO,YAAY,SAAS,iCAAiC,WAAW,OAAO,KAAK;EAC1F,IACE,MAAM,SAAS,qBACf,KAAK,SAAS,SAAS,gBACvB,KAAK,mBAAmB,UACxB,KAAK,SAAS,SAAS,MAAM,QAE7B,MAAM,IAAI,MAAM,GAAG,SAAS,IAAI,MAAM,qBAAqB,MAAM,OAAO,yBAAyB;CAErG;CACA,MAAM,cAAc,YAAY,UAAU,QAAQ;CAClD,MAAM,OAAO,IAAI,YAAY,MAAM;CACnC,KAAK,MAAM,QAAQ,CAAC,UAAU,SAAS,GAAG;EACxC,IAAI,KAAK,UAAU,QAAQ,KAAK,UAAU,UAAa,KAAK,QAAQ,QAAQ,KAAK,QAAQ,QACvF,MAAM,IAAI,MAAM,GAAG,SAAS,iDAAiD;EAE/E,KAAK,OAAO,MAAM,IAAI,MAAM,SAAS,KAAK,OAAO,MAAM,IAAI,MAAM,SAAS,KAAK,GAAG;CACpF;CACA,OAAO;EACL;EACA,MAAM,KAAK,SAAS;EACpB,KAAK,KAAK,YAAY;GAAE,QAAQ;GAAU,gBAAgB;GAAM,OAAO;EAAK,CAAC;CAC/E;AACF;AAEA,SAAS,YAAY,YAAmD,UAA+B;CACrG,QAAQ,WAAW,MAAnB;EACE,KAAK;EACL,KAAK,kBACH,OAAO,WAAW;EACpB,KAAK;GACH,IAAI,OAAO,SAAS,WAAW,KAAK,GAAG,OAAO,WAAW;GACzD;EACF,KAAK,eACH,OAAO;EACT,KAAK;GACH,IACE,WAAW,aAAa,OACxB,WAAW,SAAS,SAAS,oBAC7B,OAAO,SAAS,WAAW,SAAS,KAAK,GAEzC,OAAO,CAAC,WAAW,SAAS;GAE9B;EACF,KAAK,mBACH,OAAO,WAAW,SAAS,KAAK,YAAY;GAC1C,IAAI,CAAC,WAAW,QAAQ,SAAS,iBAC/B,MAAM,IAAI,MAAM,GAAG,SAAS,4CAA4C;GAC1E,OAAO,YAAY,SAAS,QAAQ;EACtC,CAAC;EACH,KAAK,oBAAoB;GACvB,MAAM,UAAU,WAAW,WAAW,KAAK,aAAoC;IAC7E,IACE,SAAS,SAAS,oBAClB,SAAS,YACT,SAAS,aACR,SAAS,IAAI,SAAS,gBAAgB,SAAS,IAAI,SAAS,iBAE7D,MAAM,IAAI,MACR,GAAG,SAAS,2FACd;IAEF,OAAO,CACL,SAAS,IAAI,SAAS,eAAe,SAAS,IAAI,OAAO,SAAS,IAAI,OACtE,YAAY,SAAS,OAAO,QAAQ,CACtC;GACF,CAAC;GACD,IAAI,IAAI,IAAI,QAAQ,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,QACxD,MAAM,IAAI,MAAM,GAAG,SAAS,gCAAgC;GAC9D,OAAO,OAAO,YAAY,OAAO;EACnC;CACF;CACA,MAAM,IAAI,MAAM,GAAG,SAAS,wDAAwD,WAAW,KAAK,iBAAiB;AACvH;;AAGA,SAAgB,qBAAqB,QAAgB,UAA+B;CAClF,MAAM,aAAa,WAAW,IAAI,OAAO,IAAI;EAAE,YAAY;EAAU,SAAS,CAAC,YAAY;CAAE,CAAC,CAAC,CAAC,QAAQ,KAAK;CAC7G,IAAI,YAAY,SAAS,uBAAuB,MAAM,IAAI,MAAM,GAAG,SAAS,kCAAkC;CAC9G,OAAO,YAAY,WAAW,YAAY,QAAQ;AACpD;AAEA,SAAgB,qBAAqB;CACnC,OAAO;EACL,MAAM;EACN,SAAS;EACT,UAAU,QAAgB,IAAY;GACpC,IAAI,CAAC,GAAG,SAAS,MAAM,GAAG,OAAO;GACjC,MAAM,WAAW,gBAAgB,QAAQ,EAAE;GAC3C,OAAO,WAAW;IAAE,MAAM,SAAS;IAAM,KAAK,SAAS;GAAI,IAAI;EACjE;CACF;AACF"}
@@ -0,0 +1,163 @@
1
+ import { i as BlockAuthoring, t as ComponentDefinition } from "../Configuration-BGYFD2N1.js";
2
+ import { n as parseAuthoringContent, t as createAuthoringSchema } from "../AuthoringSchema-BQ5kbhVB.js";
3
+ import { compileCmsBlock, readAuthoringDefault } from "./authoring-compiler.js";
4
+ import { Effect, Schema } from "effect";
5
+ import ts from "typescript";
6
+
7
+ //#region src/internal/authoring-metadata.ts
8
+ const Presentation = Schema.Struct({
9
+ label: Schema.NonEmptyString,
10
+ help: Schema.optionalKey(Schema.String),
11
+ input: Schema.String,
12
+ optionLabels: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
13
+ features: Schema.optionalKey(Schema.Array(Schema.Literals([
14
+ "bold",
15
+ "italic",
16
+ "link",
17
+ "bullet-list",
18
+ "code"
19
+ ])))
20
+ });
21
+ const Declaration = Schema.Struct({
22
+ label: Schema.NonEmptyString,
23
+ description: Schema.optionalKey(Schema.String),
24
+ group: Schema.optionalKey(Schema.String),
25
+ icon: Schema.optionalKey(Schema.String),
26
+ props: Schema.Record(Schema.String, Presentation),
27
+ slots: Schema.Record(Schema.String, Presentation),
28
+ initial: Schema.optionalKey(Schema.Struct({
29
+ props: Schema.optionalKey(Schema.JsonObject),
30
+ slots: Schema.optionalKey(Schema.Record(Schema.String, Schema.Union([Schema.Struct({ text: Schema.String }), Schema.Struct({ markdown: Schema.String })])))
31
+ }))
32
+ });
33
+ /** Resolves one opted-in SFC. No framework metadata or executable defaults cross this seam. */
34
+ const resolveBlockAuthoring = Effect.fn("NuxtAuthoring.resolve")(function* (checker, filename, name, source) {
35
+ const compiled = compileCmsBlock(source, filename);
36
+ if (!compiled) return void 0;
37
+ const declared = yield* Schema.decodeUnknownEffect(Declaration)(compiled.declaration, { onExcessProperty: "error" });
38
+ checker.updateFile(filename, source);
39
+ const metadata = checker.getComponentMeta(filename);
40
+ const props = Object.entries(declared.props).map(([key, presentation]) => {
41
+ const prop = metadata.props.find((candidate) => candidate.name === key && !candidate.global);
42
+ if (!prop) throw new Error(`${filename}: unknown Vue prop ${key}.`);
43
+ const resolved = scalarProp(prop, filename);
44
+ const input = presentation.input;
45
+ if (resolved.type === "string" && ![
46
+ "text",
47
+ "textarea",
48
+ "select"
49
+ ].includes(input) || resolved.type === "number" && input !== "number" || resolved.type === "boolean" && input !== "toggle" || input === "select" && !resolved.choices.length) throw new Error(`${filename}: ${key} has an incompatible authoring input ${input}.`);
50
+ for (const key of Object.keys(presentation.optionLabels ?? {})) if (!resolved.choices.includes(key)) throw new Error(`${filename}: ${key} is not a Vue union choice.`);
51
+ return Schema.decodeUnknownSync(BlockAuthoring.fields.props.value)({
52
+ name: key,
53
+ label: presentation.label,
54
+ ...presentation.help === void 0 ? void 0 : { help: presentation.help },
55
+ type: resolved.type,
56
+ input,
57
+ required: prop.required,
58
+ nullable: resolved.nullable,
59
+ ...prop.default === void 0 ? void 0 : { defaultValue: readAuthoringDefault(prop.default, `${filename} prop ${key}`) },
60
+ options: resolved.choices.map((value) => ({
61
+ value,
62
+ label: presentation.optionLabels?.[value] ?? value
63
+ }))
64
+ });
65
+ });
66
+ for (const prop of metadata.props) if (!prop.global && prop.required && prop.default === void 0 && !Object.hasOwn(declared.props, prop.name)) throw new Error(`${filename}: required prop ${prop.name} needs an authoring declaration and initial value.`);
67
+ const slotTypes = vueSlots(checker, filename);
68
+ const slots = [];
69
+ for (const [key, presentation] of Object.entries(declared.slots)) {
70
+ const slot = slotTypes.get(key);
71
+ if (!slot) throw new Error(`${filename}: unknown Vue slot ${key}.`);
72
+ if (slot.scoped) throw new Error(`${filename}: scoped slot ${key} cannot be authored.`);
73
+ const seed = declared.initial?.slots?.[key];
74
+ const initial = seed ? "text" in seed ? [[
75
+ "p",
76
+ {},
77
+ seed.text
78
+ ]] : yield* parseAuthoringContent(seed.markdown) : void 0;
79
+ slots.push(yield* Schema.decodeUnknownEffect(BlockAuthoring.fields.slots.value)({
80
+ name: key,
81
+ label: presentation.label,
82
+ ...presentation.help === void 0 ? void 0 : { help: presentation.help },
83
+ input: presentation.input,
84
+ required: slot.required,
85
+ features: presentation.features ?? [],
86
+ ...initial === void 0 ? void 0 : { initial }
87
+ }));
88
+ if (slot.required && !seed) throw new Error(`${filename}: required slot ${key} needs initial content.`);
89
+ }
90
+ for (const [key, slot] of slotTypes) if (slot.required && !Object.hasOwn(declared.slots, key)) throw new Error(`${filename}: required slot ${key} must be declared.`);
91
+ for (const key of Object.keys(declared.initial?.slots ?? {})) if (!slotTypes.has(key) || !Object.hasOwn(declared.slots, key)) throw new Error(`${filename}: initial content refers to undeclared slot ${key}.`);
92
+ const authoring = BlockAuthoring.make({
93
+ version: 1,
94
+ label: declared.label,
95
+ props,
96
+ slots,
97
+ initialProps: declared.initial?.props ?? {},
98
+ ...declared.description === void 0 ? void 0 : { description: declared.description },
99
+ ...declared.group === void 0 ? void 0 : { group: declared.group },
100
+ ...declared.icon === void 0 ? void 0 : { icon: declared.icon }
101
+ });
102
+ createAuthoringSchema(name, authoring);
103
+ return ComponentDefinition.make({
104
+ name,
105
+ authoring,
106
+ props: props.map(({ name, required, type }) => ({
107
+ name,
108
+ required,
109
+ type
110
+ })),
111
+ slots: slots.map(({ name }) => ({ name }))
112
+ });
113
+ });
114
+ function scalarProp(prop, filename) {
115
+ const raw = prop.getTypeObject();
116
+ const union = raw.isUnion() ? raw.types : [raw];
117
+ const members = union.filter((type) => !(type.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)));
118
+ const nullable = union.some((type) => Boolean(type.flags & ts.TypeFlags.Null));
119
+ const choices = members.flatMap((type) => type.isStringLiteral() ? [type.value] : []).sort();
120
+ if (members.length && members.every((type) => Boolean(type.flags & ts.TypeFlags.StringLike))) return {
121
+ type: "string",
122
+ nullable,
123
+ choices
124
+ };
125
+ if (members.length === 1 && members[0]?.flags === ts.TypeFlags.Number) return {
126
+ type: "number",
127
+ nullable,
128
+ choices
129
+ };
130
+ if (members.length === 2 && members.every((type) => Boolean(type.flags & ts.TypeFlags.BooleanLiteral))) return {
131
+ type: "boolean",
132
+ nullable,
133
+ choices
134
+ };
135
+ throw new Error(`${filename}: editable prop ${prop.name} must be a string, literal string union, number, or boolean.`);
136
+ }
137
+ function vueSlots(checker, filename) {
138
+ const program = checker.getProgram();
139
+ const file = program?.getSourceFile(filename);
140
+ if (!program || !file) throw new Error(`${filename}: Vue type information is unavailable.`);
141
+ const typeChecker = program.getTypeChecker();
142
+ const result = /* @__PURE__ */ new Map();
143
+ function visit(node) {
144
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "defineSlots") {
145
+ const type = node.typeArguments?.[0];
146
+ if (type) for (const property of typeChecker.getTypeAtLocation(type).getProperties()) {
147
+ const declaration = property.valueDeclaration ?? property.declarations?.[0];
148
+ const signature = declaration ? typeChecker.getNonNullableType(typeChecker.getTypeOfSymbolAtLocation(property, declaration)).getCallSignatures() : [];
149
+ result.set(property.name, {
150
+ required: !(property.flags & ts.SymbolFlags.Optional),
151
+ scoped: signature.length !== 1 || signature.some((signature) => signature.parameters.length > 0)
152
+ });
153
+ }
154
+ }
155
+ ts.forEachChild(node, visit);
156
+ }
157
+ visit(file);
158
+ return result;
159
+ }
160
+
161
+ //#endregion
162
+ export { resolveBlockAuthoring };
163
+ //# sourceMappingURL=authoring-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-metadata.js","names":[],"sources":["../../../../src/internal/authoring-metadata.ts"],"sourcesContent":["import type { ComponentMetaChecker, PropertyMeta } from 'vue-component-meta'\nimport type { BlockProp, BlockSlot } from '@internal/protocol/Authoring'\nimport { createAuthoringSchema, parseAuthoringContent } from '@internal/document/AuthoringSchema'\nimport { BlockAuthoring } from '@internal/protocol/Authoring'\nimport { ComponentDefinition } from '@internal/protocol/Configuration'\nimport { Effect, Schema } from 'effect'\nimport ts from 'typescript'\nimport { compileCmsBlock, readAuthoringDefault } from './authoring-compiler'\n\nconst Presentation = Schema.Struct({\n label: Schema.NonEmptyString,\n help: Schema.optionalKey(Schema.String),\n input: Schema.String,\n optionLabels: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),\n features: Schema.optionalKey(Schema.Array(Schema.Literals(['bold', 'italic', 'link', 'bullet-list', 'code']))),\n})\nconst Declaration = Schema.Struct({\n label: Schema.NonEmptyString,\n description: Schema.optionalKey(Schema.String),\n group: Schema.optionalKey(Schema.String),\n icon: Schema.optionalKey(Schema.String),\n props: Schema.Record(Schema.String, Presentation),\n slots: Schema.Record(Schema.String, Presentation),\n initial: Schema.optionalKey(\n Schema.Struct({\n props: Schema.optionalKey(Schema.JsonObject),\n slots: Schema.optionalKey(\n Schema.Record(\n Schema.String,\n Schema.Union([Schema.Struct({ text: Schema.String }), Schema.Struct({ markdown: Schema.String })]),\n ),\n ),\n }),\n ),\n})\n\n/** Resolves one opted-in SFC. No framework metadata or executable defaults cross this seam. */\nexport const resolveBlockAuthoring = Effect.fn('NuxtAuthoring.resolve')(function* (\n checker: ComponentMetaChecker,\n filename: string,\n name: string,\n source: string,\n) {\n const compiled = compileCmsBlock(source, filename)\n if (!compiled) return undefined\n const declared = yield* Schema.decodeUnknownEffect(Declaration)(compiled.declaration, { onExcessProperty: 'error' })\n checker.updateFile(filename, source)\n const metadata = checker.getComponentMeta(filename)\n const props = Object.entries(declared.props).map(([key, presentation]): BlockProp => {\n const prop = metadata.props.find((candidate) => candidate.name === key && !candidate.global)\n if (!prop) throw new Error(`${filename}: unknown Vue prop ${key}.`)\n const resolved = scalarProp(prop, filename)\n const input = presentation.input\n if (\n (resolved.type === 'string' && !['text', 'textarea', 'select'].includes(input)) ||\n (resolved.type === 'number' && input !== 'number') ||\n (resolved.type === 'boolean' && input !== 'toggle') ||\n (input === 'select' && !resolved.choices.length)\n )\n throw new Error(`${filename}: ${key} has an incompatible authoring input ${input}.`)\n for (const key of Object.keys(presentation.optionLabels ?? {}))\n if (!resolved.choices.includes(key)) throw new Error(`${filename}: ${key} is not a Vue union choice.`)\n return Schema.decodeUnknownSync(BlockAuthoring.fields.props.value)({\n name: key,\n label: presentation.label,\n ...(presentation.help === undefined ? undefined : { help: presentation.help }),\n type: resolved.type,\n input,\n required: prop.required,\n nullable: resolved.nullable,\n ...(prop.default === undefined\n ? undefined\n : { defaultValue: readAuthoringDefault(prop.default, `${filename} prop ${key}`) }),\n options: resolved.choices.map((value) => ({ value, label: presentation.optionLabels?.[value] ?? value })),\n })\n })\n for (const prop of metadata.props) {\n if (!prop.global && prop.required && prop.default === undefined && !Object.hasOwn(declared.props, prop.name))\n throw new Error(`${filename}: required prop ${prop.name} needs an authoring declaration and initial value.`)\n }\n const slotTypes = vueSlots(checker, filename)\n const slots: BlockSlot[] = []\n for (const [key, presentation] of Object.entries(declared.slots)) {\n const slot = slotTypes.get(key)\n if (!slot) throw new Error(`${filename}: unknown Vue slot ${key}.`)\n if (slot.scoped) throw new Error(`${filename}: scoped slot ${key} cannot be authored.`)\n const seed = declared.initial?.slots?.[key]\n const initial = seed\n ? 'text' in seed\n ? [['p', {}, seed.text]]\n : yield* parseAuthoringContent(seed.markdown)\n : undefined\n slots.push(\n yield* Schema.decodeUnknownEffect(BlockAuthoring.fields.slots.value)({\n name: key,\n label: presentation.label,\n ...(presentation.help === undefined ? undefined : { help: presentation.help }),\n input: presentation.input,\n required: slot.required,\n features: presentation.features ?? [],\n ...(initial === undefined ? undefined : { initial }),\n }),\n )\n if (slot.required && !seed) throw new Error(`${filename}: required slot ${key} needs initial content.`)\n }\n for (const [key, slot] of slotTypes)\n if (slot.required && !Object.hasOwn(declared.slots, key))\n throw new Error(`${filename}: required slot ${key} must be declared.`)\n for (const key of Object.keys(declared.initial?.slots ?? {}))\n if (!slotTypes.has(key) || !Object.hasOwn(declared.slots, key))\n throw new Error(`${filename}: initial content refers to undeclared slot ${key}.`)\n const authoring = BlockAuthoring.make({\n version: 1,\n label: declared.label,\n props,\n slots,\n initialProps: declared.initial?.props ?? {},\n ...(declared.description === undefined ? undefined : { description: declared.description }),\n ...(declared.group === undefined ? undefined : { group: declared.group }),\n ...(declared.icon === undefined ? undefined : { icon: declared.icon }),\n })\n createAuthoringSchema(name, authoring)\n return ComponentDefinition.make({\n name,\n authoring,\n props: props.map(({ name, required, type }) => ({ name, required, type })),\n slots: slots.map(({ name }) => ({ name })),\n })\n})\n\nfunction scalarProp(prop: PropertyMeta, filename: string) {\n const raw = prop.getTypeObject()\n const union = raw.isUnion() ? raw.types : [raw]\n const members = union.filter((type) => !(type.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)))\n const nullable = union.some((type) => Boolean(type.flags & ts.TypeFlags.Null))\n const choices = members.flatMap((type) => (type.isStringLiteral() ? [type.value] : [])).sort()\n if (members.length && members.every((type) => Boolean(type.flags & ts.TypeFlags.StringLike)))\n return { type: 'string' as const, nullable, choices }\n if (members.length === 1 && members[0]?.flags === ts.TypeFlags.Number)\n return { type: 'number' as const, nullable, choices }\n if (members.length === 2 && members.every((type) => Boolean(type.flags & ts.TypeFlags.BooleanLiteral)))\n return { type: 'boolean' as const, nullable, choices }\n throw new Error(`${filename}: editable prop ${prop.name} must be a string, literal string union, number, or boolean.`)\n}\n\nfunction vueSlots(checker: ComponentMetaChecker, filename: string) {\n const program = checker.getProgram()\n const file = program?.getSourceFile(filename)\n if (!program || !file) throw new Error(`${filename}: Vue type information is unavailable.`)\n const typeChecker = program.getTypeChecker()\n const result = new Map<string, { required: boolean; scoped: boolean }>()\n function visit(node: ts.Node): void {\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'defineSlots') {\n const type = node.typeArguments?.[0]\n if (type)\n for (const property of typeChecker.getTypeAtLocation(type).getProperties()) {\n const declaration = property.valueDeclaration ?? property.declarations?.[0]\n const signature = declaration\n ? typeChecker\n .getNonNullableType(typeChecker.getTypeOfSymbolAtLocation(property, declaration))\n .getCallSignatures()\n : []\n result.set(property.name, {\n required: !(property.flags & ts.SymbolFlags.Optional),\n scoped: signature.length !== 1 || signature.some((signature) => signature.parameters.length > 0),\n })\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(file)\n return result\n}\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { Effect, FileSystem, Path, Schema } from "effect";
2
+ import { createJiti } from "jiti";
3
+
4
+ //#region src/internal/cms-config.ts
5
+ const CMS_CONFIG_NAMES = [
6
+ "cms.config.ts",
7
+ "cms.config.mts",
8
+ "cms.config.js",
9
+ "cms.config.mjs"
10
+ ];
11
+ const jiti = createJiti(import.meta.url);
12
+ var CmsConfigurationLoadFailed = class extends Schema.TaggedError()("CmsConfigurationLoadFailed", {
13
+ cause: Schema.Defect(),
14
+ operation: Schema.String
15
+ }) {};
16
+ /** Loads the conventional executable CMS configuration without routing it through Nuxt options. */
17
+ const loadCmsConfiguration = Effect.fn("CmsConfiguration.load")(function* (rootDir) {
18
+ const fileSystem = yield* FileSystem.FileSystem;
19
+ const paths = yield* Path.Path;
20
+ let configurationPath;
21
+ for (const name of CMS_CONFIG_NAMES) {
22
+ const candidate = paths.join(rootDir, name);
23
+ if (yield* fileSystem.exists(candidate)) {
24
+ configurationPath = candidate;
25
+ break;
26
+ }
27
+ }
28
+ if (!configurationPath) return yield* new CmsConfigurationLoadFailed({
29
+ cause: /* @__PURE__ */ new Error(`CMS configuration is missing. Create ${paths.join(rootDir, "cms.config.ts")}.`),
30
+ operation: "CmsConfiguration.locate"
31
+ });
32
+ return {
33
+ configuration: yield* Effect.tryPromise({
34
+ try: () => jiti.import(configurationPath, { default: true }),
35
+ catch: (cause) => new CmsConfigurationLoadFailed({
36
+ cause,
37
+ operation: "CmsConfiguration.import"
38
+ })
39
+ }),
40
+ path: configurationPath
41
+ };
42
+ });
43
+
44
+ //#endregion
45
+ export { loadCmsConfiguration };
46
+ //# sourceMappingURL=cms-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-config.js","names":[],"sources":["../../../../src/internal/cms-config.ts"],"sourcesContent":["import type { CmsConfiguration } from '../Configuration'\nimport { Effect, FileSystem, Path, Schema } from 'effect'\nimport { createJiti } from 'jiti'\n\nconst CMS_CONFIG_NAMES = ['cms.config.ts', 'cms.config.mts', 'cms.config.js', 'cms.config.mjs']\nconst jiti = createJiti(import.meta.url)\n\nclass CmsConfigurationLoadFailed extends Schema.TaggedError<CmsConfigurationLoadFailed>()(\n 'CmsConfigurationLoadFailed',\n { cause: Schema.Defect(), operation: Schema.String },\n) {}\n\n/** Loads the conventional executable CMS configuration without routing it through Nuxt options. */\nexport const loadCmsConfiguration = Effect.fn('CmsConfiguration.load')(function* (rootDir: string) {\n const fileSystem = yield* FileSystem.FileSystem\n const paths = yield* Path.Path\n let configurationPath: string | undefined\n for (const name of CMS_CONFIG_NAMES) {\n const candidate = paths.join(rootDir, name)\n if (yield* fileSystem.exists(candidate)) {\n configurationPath = candidate\n break\n }\n }\n if (!configurationPath) {\n return yield* new CmsConfigurationLoadFailed({\n cause: new Error(`CMS configuration is missing. Create ${paths.join(rootDir, 'cms.config.ts')}.`),\n operation: 'CmsConfiguration.locate',\n })\n }\n const configuration = yield* Effect.tryPromise({\n try: () => jiti.import<CmsConfiguration>(configurationPath, { default: true }),\n catch: (cause) => new CmsConfigurationLoadFailed({ cause, operation: 'CmsConfiguration.import' }),\n })\n return { configuration, path: configurationPath }\n})\n"],"mappings":";;;;AAIA,MAAM,mBAAmB;CAAC;CAAiB;CAAkB;CAAiB;AAAgB;AAC9F,MAAM,OAAO,WAAW,YAAY,GAAG;AAEvC,IAAM,6BAAN,cAAyC,OAAO,YAAwC,CAAC,CACvF,8BACA;CAAE,OAAO,OAAO,OAAO;CAAG,WAAW,OAAO;AAAO,CACrD,CAAC,CAAC,CAAC;;AAGH,MAAa,uBAAuB,OAAO,GAAG,uBAAuB,CAAC,CAAC,WAAW,SAAiB;CACjG,MAAM,aAAa,OAAO,WAAW;CACrC,MAAM,QAAQ,OAAO,KAAK;CAC1B,IAAI;CACJ,KAAK,MAAM,QAAQ,kBAAkB;EACnC,MAAM,YAAY,MAAM,KAAK,SAAS,IAAI;EAC1C,IAAI,OAAO,WAAW,OAAO,SAAS,GAAG;GACvC,oBAAoB;GACpB;EACF;CACF;CACA,IAAI,CAAC,mBACH,OAAO,OAAO,IAAI,2BAA2B;EAC3C,uBAAO,IAAI,MAAM,wCAAwC,MAAM,KAAK,SAAS,eAAe,EAAE,EAAE;EAChG,WAAW;CACb,CAAC;CAMH,OAAO;EAAE,sBAJoB,OAAO,WAAW;GAC7C,WAAW,KAAK,OAAyB,mBAAmB,EAAE,SAAS,KAAK,CAAC;GAC7E,QAAQ,UAAU,IAAI,2BAA2B;IAAE;IAAO,WAAW;GAA0B,CAAC;EAClG,CAAC;EACuB,MAAM;CAAkB;AAClD,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { t as ComponentDefinition } from "../Configuration-BGYFD2N1.js";
2
+
3
+ //#region src/internal/component-metadata.ts
4
+ function cmsComponentDefinitions(metadata) {
5
+ const definitions = Object.values(metadata).filter((component) => component.global !== false).map((component) => ComponentDefinition.make({
6
+ name: component.kebabName,
7
+ props: component.meta.props.filter((prop) => !prop.global).map((prop) => ({
8
+ name: prop.name,
9
+ required: prop.required,
10
+ type: componentPropType(component.pascalName, prop.name, prop.type)
11
+ })),
12
+ slots: component.meta.slots.map((slot) => ({ name: slot.name }))
13
+ })).sort((left, right) => left.name.localeCompare(right.name));
14
+ const names = /* @__PURE__ */ new Set();
15
+ for (const definition of definitions) {
16
+ if (names.has(definition.name)) throw new Error(`Global document component "${definition.name}" is defined more than once.`);
17
+ names.add(definition.name);
18
+ }
19
+ return definitions;
20
+ }
21
+ function componentPropType(componentName, propName, declaredType) {
22
+ const classified = declaredType.split("|").map((member) => member.trim()).filter((member) => member !== "null" && member !== "undefined").map(classifyPropType);
23
+ const types = new Set(classified);
24
+ if (!classified.includes(void 0) && types.size === 1) return [...types][0];
25
+ throw new Error(`Global document component "${componentName}" prop "${propName}" has unsupported type "${declaredType}". Use one JSON-compatible string, number, boolean, array, or object type.`);
26
+ }
27
+ function classifyPropType(type) {
28
+ if (type === "string" || /^(['"]).*\1$/u.test(type)) return "string";
29
+ if (type === "number" || /^-?\d+(?:\.\d+)?$/u.test(type)) return "number";
30
+ if (type === "boolean" || type === "true" || type === "false") return "boolean";
31
+ if (/^(?:readonly\s+)?(?:Array|ReadonlyArray)</u.test(type) || type.endsWith("[]") || type.startsWith("[")) return "array";
32
+ if (type === "object" || type.startsWith("{") || /^(?:Readonly|Record)</u.test(type)) return "object";
33
+ }
34
+
35
+ //#endregion
36
+ export { cmsComponentDefinitions };
37
+ //# sourceMappingURL=component-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-metadata.js","names":["ComponentDefinitionSchema"],"sources":["../../../../src/internal/component-metadata.ts"],"sourcesContent":["import type { ComponentDefinition, ComponentPropDefinition } from '@internal/protocol/Configuration'\nimport { ComponentDefinition as ComponentDefinitionSchema } from '@internal/protocol/Configuration'\n\ninterface NuxtComponentMetadata {\n readonly global?: boolean | 'sync'\n readonly kebabName: string\n readonly meta: {\n readonly props: ReadonlyArray<{\n readonly global: boolean\n readonly name: string\n readonly required: boolean\n readonly type: string\n }>\n readonly slots: ReadonlyArray<{ readonly name: string }>\n }\n readonly pascalName: string\n}\n\nexport function cmsComponentDefinitions(\n metadata: Readonly<Record<string, NuxtComponentMetadata>>,\n): ReadonlyArray<ComponentDefinition> {\n const definitions = Object.values(metadata)\n // nuxt-component-meta is configured with globalsOnly; undefined means a\n // globally available component whose registration mode was not annotated.\n .filter((component) => component.global !== false)\n .map((component) =>\n ComponentDefinitionSchema.make({\n name: component.kebabName,\n props: component.meta.props\n .filter((prop) => !prop.global)\n .map((prop) => ({\n name: prop.name,\n required: prop.required,\n type: componentPropType(component.pascalName, prop.name, prop.type),\n })),\n slots: component.meta.slots.map((slot) => ({ name: slot.name })),\n }),\n )\n .sort((left, right) => left.name.localeCompare(right.name))\n\n const names = new Set<string>()\n for (const definition of definitions) {\n if (names.has(definition.name))\n throw new Error(`Global document component \"${definition.name}\" is defined more than once.`)\n names.add(definition.name)\n }\n return definitions\n}\n\nfunction componentPropType(\n componentName: string,\n propName: string,\n declaredType: string,\n): ComponentPropDefinition['type'] {\n const members = declaredType\n .split('|')\n .map((member) => member.trim())\n .filter((member) => member !== 'null' && member !== 'undefined')\n const classified = members.map(classifyPropType)\n const types = new Set(classified)\n if (!classified.includes(undefined) && types.size === 1) return [...types][0]!\n throw new Error(\n `Global document component \"${componentName}\" prop \"${propName}\" has unsupported type \"${declaredType}\". ` +\n 'Use one JSON-compatible string, number, boolean, array, or object type.',\n )\n}\n\nfunction classifyPropType(type: string): ComponentPropDefinition['type'] | undefined {\n if (type === 'string' || /^(['\"]).*\\1$/u.test(type)) return 'string'\n if (type === 'number' || /^-?\\d+(?:\\.\\d+)?$/u.test(type)) return 'number'\n if (type === 'boolean' || type === 'true' || type === 'false') return 'boolean'\n if (/^(?:readonly\\s+)?(?:Array|ReadonlyArray)</u.test(type) || type.endsWith('[]') || type.startsWith('['))\n return 'array'\n if (type === 'object' || type.startsWith('{') || /^(?:Readonly|Record)</u.test(type)) return 'object'\n return undefined\n}\n"],"mappings":";;;AAkBA,SAAgB,wBACd,UACoC;CACpC,MAAM,cAAc,OAAO,OAAO,QAAQ,CAAC,CAGxC,QAAQ,cAAc,UAAU,WAAW,KAAK,CAAC,CACjD,KAAK,cACJA,oBAA0B,KAAK;EAC7B,MAAM,UAAU;EAChB,OAAO,UAAU,KAAK,MACnB,QAAQ,SAAS,CAAC,KAAK,MAAM,CAAC,CAC9B,KAAK,UAAU;GACd,MAAM,KAAK;GACX,UAAU,KAAK;GACf,MAAM,kBAAkB,UAAU,YAAY,KAAK,MAAM,KAAK,IAAI;EACpE,EAAE;EACJ,OAAO,UAAU,KAAK,MAAM,KAAK,UAAU,EAAE,MAAM,KAAK,KAAK,EAAE;CACjE,CAAC,CACH,CAAC,CACA,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;CAE5D,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,MAAM,IAAI,WAAW,IAAI,GAC3B,MAAM,IAAI,MAAM,8BAA8B,WAAW,KAAK,6BAA6B;EAC7F,MAAM,IAAI,WAAW,IAAI;CAC3B;CACA,OAAO;AACT;AAEA,SAAS,kBACP,eACA,UACA,cACiC;CAKjC,MAAM,aAJU,aACb,MAAM,GAAG,CAAC,CACV,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAC9B,QAAQ,WAAW,WAAW,UAAU,WAAW,WAC7B,CAAC,CAAC,IAAI,gBAAgB;CAC/C,MAAM,QAAQ,IAAI,IAAI,UAAU;CAChC,IAAI,CAAC,WAAW,SAAS,MAAS,KAAK,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;CAC3E,MAAM,IAAI,MACR,8BAA8B,cAAc,UAAU,SAAS,0BAA0B,aAAa,2EAExG;AACF;AAEA,SAAS,iBAAiB,MAA2D;CACnF,IAAI,SAAS,YAAY,gBAAgB,KAAK,IAAI,GAAG,OAAO;CAC5D,IAAI,SAAS,YAAY,qBAAqB,KAAK,IAAI,GAAG,OAAO;CACjE,IAAI,SAAS,aAAa,SAAS,UAAU,SAAS,SAAS,OAAO;CACtE,IAAI,6CAA6C,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,WAAW,GAAG,GACvG,OAAO;CACT,IAAI,SAAS,YAAY,KAAK,WAAW,GAAG,KAAK,yBAAyB,KAAK,IAAI,GAAG,OAAO;AAE/F"}
@@ -0,0 +1,93 @@
1
+ import { u as DocumentImportSource } from "../models-Citx8jBi.js";
2
+ import { a as StudioBootstrap } from "../StudioHttp-BTLLooh0.js";
3
+ import { s as PreviewOrigin } from "../models-DS5ClMsH.js";
4
+ import { cmsComponentDefinitions } from "./component-metadata.js";
5
+ import { compileCmsDocumentModel } from "./document-model.js";
6
+ import { Result, Schema } from "effect";
7
+
8
+ //#region src/internal/configuration.ts
9
+ const DEFAULT_CLEANUP_INTERVAL_MILLIS = 864e5;
10
+ const DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS = 6e4;
11
+ const DEFAULT_MEDIA_MAX_UPLOAD_BYTES = 1e7;
12
+ const optionalString = Schema.optionalKey(Schema.NonEmptyString);
13
+ const InstallationConfiguration = Schema.Struct({
14
+ baseUrl: PreviewOrigin,
15
+ cleanup: Schema.optionalKey(Schema.Union([Schema.Literals([false]), Schema.Struct({
16
+ initialDelayMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),
17
+ intervalMillis: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0)))
18
+ })])),
19
+ databaseUrl: Schema.NonEmptyString,
20
+ initializationToken: Schema.NonEmptyString.check(Schema.isMinLength(32)),
21
+ media: Schema.optionalKey(Schema.Union([Schema.Literals([false]), Schema.Struct({
22
+ maxUploadBytes: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0))),
23
+ publicBaseUrl: Schema.NonEmptyString,
24
+ storage: Schema.Struct({
25
+ bucket: Schema.NonEmptyString,
26
+ credentials: Schema.optionalKey(Schema.Struct({
27
+ accessKeyId: Schema.NonEmptyString,
28
+ secretAccessKey: Schema.NonEmptyString,
29
+ sessionToken: optionalString
30
+ })),
31
+ endpoint: optionalString,
32
+ forcePathStyle: Schema.optionalKey(Schema.Boolean),
33
+ provisionBucket: Schema.optionalKey(Schema.Boolean),
34
+ region: Schema.NonEmptyString
35
+ })
36
+ })])),
37
+ secret: Schema.NonEmptyString.check(Schema.isMinLength(32))
38
+ });
39
+ /** Compiles every authored, executable concern once through the owning document interface. */
40
+ function compileCmsConfiguration(configuration, initialSources = []) {
41
+ const decodedConfiguration = Schema.decodeResult(InstallationConfiguration)(configuration);
42
+ if (Result.isFailure(decodedConfiguration)) throw new Error(`Invalid CMS configuration: ${String(decodedConfiguration.failure)}`);
43
+ const documents = compileCmsDocumentModel(configuration.documents);
44
+ const decodedSources = Schema.decodeResult(Schema.Array(DocumentImportSource))(initialSources);
45
+ if (Result.isFailure(decodedSources)) throw new Error(`Invalid CMS initial sources: ${String(decodedSources.failure)}`);
46
+ return {
47
+ documentModel: documents.executable,
48
+ documents: documents.authoring,
49
+ initialSources: decodedSources.success,
50
+ installation: decodedConfiguration.success
51
+ };
52
+ }
53
+ /** Produces the single input consumed by the Node installation from the authored CMS configuration. */
54
+ function resolveCmsInstallation(authored, componentMetadata, initialSources = [], authoring = []) {
55
+ const compiled = compileCmsConfiguration(authored, initialSources);
56
+ const configuration = compiled.installation;
57
+ const cleanup = configuration.cleanup === false ? void 0 : configuration.cleanup;
58
+ const media = configuration.media === false ? void 0 : configuration.media;
59
+ const bootstrap = Schema.decodeSync(StudioBootstrap)({
60
+ basePath: "/",
61
+ components: [...cmsComponentDefinitions(Object.fromEntries(Object.entries(componentMetadata).filter(([, component]) => !authoring.some((definition) => definition.name === component.kebabName)))), ...authoring].sort((left, right) => left.name.localeCompare(right.name)),
62
+ documents: compiled.documents,
63
+ media: {
64
+ enabled: media !== void 0,
65
+ maxUploadBytes: media?.maxUploadBytes ?? DEFAULT_MEDIA_MAX_UPLOAD_BYTES
66
+ },
67
+ version: "1"
68
+ });
69
+ return {
70
+ baseUrl: configuration.baseUrl,
71
+ bootstrap,
72
+ cleanup: {
73
+ enabled: configuration.cleanup !== false,
74
+ initialDelayMillis: cleanup?.initialDelayMillis ?? DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS,
75
+ intervalMillis: cleanup?.intervalMillis ?? DEFAULT_CLEANUP_INTERVAL_MILLIS
76
+ },
77
+ databaseUrl: configuration.databaseUrl,
78
+ documentModel: compiled.documentModel,
79
+ initialSources: compiled.initialSources,
80
+ initializationToken: configuration.initializationToken,
81
+ ...media === void 0 ? void 0 : { media: {
82
+ publicBaseUrl: media.publicBaseUrl,
83
+ ...media.storage,
84
+ forcePathStyle: media.storage.forcePathStyle ?? false,
85
+ provisionBucket: media.storage.provisionBucket ?? false
86
+ } },
87
+ secret: configuration.secret
88
+ };
89
+ }
90
+
91
+ //#endregion
92
+ export { compileCmsConfiguration, resolveCmsInstallation };
93
+ //# sourceMappingURL=configuration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configuration.js","names":["PreviewOriginSchema","DocumentImportSourceSchema","compileComponentDefinitions"],"sources":["../../../../src/internal/configuration.ts"],"sourcesContent":["import type { ExecutableDocumentModel } from '@internal/document/DocumentEngine'\nimport type { ComponentDefinition, DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { DocumentImportSource } from '@internal/protocol/Documents'\nimport type { CmsConfiguration, CmsInitialDocument } from '../Configuration'\nimport type { cmsComponentDefinitions } from './component-metadata'\nimport type { NuxtCmsInstallationOptions } from '../runtime/installation'\nimport { DocumentImportSource as DocumentImportSourceSchema } from '@internal/protocol/Documents'\nimport { PreviewOrigin as PreviewOriginSchema } from '@internal/protocol/Preview'\nimport { StudioBootstrap } from '@internal/protocol/StudioHttp'\nimport { Result, Schema } from 'effect'\nimport { cmsComponentDefinitions as compileComponentDefinitions } from './component-metadata'\nimport { compileCmsDocumentModel } from './document-model'\n\nconst DEFAULT_CLEANUP_INTERVAL_MILLIS = 24 * 60 * 60_000\nconst DEFAULT_CLEANUP_INITIAL_DELAY_MILLIS = 60_000\nconst DEFAULT_MEDIA_MAX_UPLOAD_BYTES = 10_000_000\n\nconst optionalString = Schema.optionalKey(Schema.NonEmptyString)\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(Schema.Int.check(Schema.isGreaterThan(0))),\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 secret: Schema.NonEmptyString.check(Schema.isMinLength(32)),\n})\ntype CmsInstallationConfiguration = Schema.Schema.Type<typeof InstallationConfiguration>\n\nexport interface CompiledCmsConfiguration {\n readonly documents: DocumentConfiguration\n readonly documentModel: ExecutableDocumentModel\n readonly initialSources: ReadonlyArray<DocumentImportSource>\n readonly installation: CmsInstallationConfiguration\n}\n\n/** Compiles every authored, executable concern once through the owning document interface. */\nexport function compileCmsConfiguration(\n configuration: CmsConfiguration,\n initialSources: ReadonlyArray<CmsInitialDocument> = [],\n): CompiledCmsConfiguration {\n const decodedConfiguration = Schema.decodeResult(InstallationConfiguration)(configuration)\n if (Result.isFailure(decodedConfiguration)) {\n throw new Error(`Invalid CMS configuration: ${String(decodedConfiguration.failure)}`)\n }\n const documents = compileCmsDocumentModel(configuration.documents)\n const decodedSources = Schema.decodeResult(Schema.Array(DocumentImportSourceSchema))(initialSources)\n if (Result.isFailure(decodedSources)) {\n throw new Error(`Invalid CMS initial sources: ${String(decodedSources.failure)}`)\n }\n return {\n documentModel: documents.executable,\n documents: documents.authoring,\n initialSources: decodedSources.success,\n installation: decodedConfiguration.success,\n }\n}\n\n/** Produces the single input consumed by the Node installation from the authored CMS configuration. */\nexport function resolveCmsInstallation(\n authored: CmsConfiguration,\n componentMetadata: Parameters<typeof cmsComponentDefinitions>[0],\n initialSources: ReadonlyArray<CmsInitialDocument> = [],\n authoring: ReadonlyArray<ComponentDefinition> = [],\n): NuxtCmsInstallationOptions {\n const compiled = compileCmsConfiguration(authored, initialSources)\n const configuration = compiled.installation\n const cleanup = configuration.cleanup === false ? undefined : configuration.cleanup\n const media = configuration.media === false ? undefined : configuration.media\n const bootstrap = Schema.decodeSync(StudioBootstrap)({\n basePath: '/',\n components: [\n ...compileComponentDefinitions(\n Object.fromEntries(\n Object.entries(componentMetadata).filter(\n ([, component]) => !authoring.some((definition) => definition.name === component.kebabName),\n ),\n ),\n ),\n ...authoring,\n ].sort((left, right) => left.name.localeCompare(right.name)),\n documents: compiled.documents,\n media: {\n enabled: media !== undefined,\n maxUploadBytes: media?.maxUploadBytes ?? DEFAULT_MEDIA_MAX_UPLOAD_BYTES,\n },\n version: '1',\n })\n\n return {\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 initialSources: compiled.initialSources,\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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"}