@phtngyn/cms 0.2.0-beta.3 → 0.2.0-beta.5

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 (121) hide show
  1. package/README.md +31 -13
  2. package/package.json +7 -7
  3. package/src/ApplicationTypes.d.ts +3 -3
  4. package/src/Authoring.d.ts +11 -3
  5. package/src/{Configuration-BU-UyGoH.js → Configuration-JQ1qyaU0.js} +347 -189
  6. package/src/Configuration-JQ1qyaU0.js.map +1 -0
  7. package/src/Configuration.d.ts +1 -1
  8. package/src/Content.d.ts +7 -6
  9. package/src/Content.js +106 -47
  10. package/src/Content.js.map +1 -1
  11. package/src/ContentTransfer-BxwswWn3.js +86 -0
  12. package/src/ContentTransfer-BxwswWn3.js.map +1 -0
  13. package/src/{ContentTransfer-CRQet3QJ.d.ts → ContentTransfer-Z9FHyLez.d.ts} +33 -9
  14. package/src/{DocumentEngine-ClhFXW9M.js → DocumentEngine-j6Vi7nQo.js} +279 -178
  15. package/src/DocumentEngine-j6Vi7nQo.js.map +1 -0
  16. package/src/DocumentModel.d.ts +9 -2
  17. package/src/DocumentModel.js +17 -4
  18. package/src/DocumentModel.js.map +1 -1
  19. package/src/{Forms-DoB56hfe.js → Forms-CX-hwmJF.js} +18 -11
  20. package/src/Forms-CX-hwmJF.js.map +1 -0
  21. package/src/{Forms-BbkE7QfC.js → Forms-CfNPTiCr.js} +2 -2
  22. package/src/{Forms-BbkE7QfC.js.map → Forms-CfNPTiCr.js.map} +1 -1
  23. package/src/Media-j1bTritO.js +112 -0
  24. package/src/Media-j1bTritO.js.map +1 -0
  25. package/src/Module.js +0 -4
  26. package/src/Module.js.map +1 -1
  27. package/src/References-CCPDAPve.js +45 -0
  28. package/src/References-CCPDAPve.js.map +1 -0
  29. package/src/{S3MediaObjects-CR3p1WTg.js → S3MediaObjects-BRuPQbxl.js} +454 -516
  30. package/src/S3MediaObjects-BRuPQbxl.js.map +1 -0
  31. package/src/cli/content.js +6 -5
  32. package/src/cli/content.js.map +1 -1
  33. package/src/cli.js +16 -3
  34. package/src/cli.js.map +1 -1
  35. package/src/{connection-D5S9Iph-.js → connection-BP80q4d-.js} +2 -2
  36. package/src/{connection-D5S9Iph-.js.map → connection-BP80q4d-.js.map} +1 -1
  37. package/src/{dev-lifecycle-D3f9-upa.js → dev-lifecycle-DdBluSiR.js} +26 -6
  38. package/src/dev-lifecycle-DdBluSiR.js.map +1 -0
  39. package/src/{installation-fZtNxtoW.js → installation-BoG8E3nJ.js} +7982 -7155
  40. package/src/installation-BoG8E3nJ.js.map +1 -0
  41. package/src/internal/authoring-catalog.js +2 -2
  42. package/src/internal/authoring-compiler.js +35 -9
  43. package/src/internal/authoring-compiler.js.map +1 -1
  44. package/src/internal/authoring-metadata.js +14 -5
  45. package/src/internal/authoring-metadata.js.map +1 -1
  46. package/src/internal/configuration.js +27 -3
  47. package/src/internal/configuration.js.map +1 -1
  48. package/src/internal/dev-lifecycle.js +2 -2
  49. package/src/internal/document-model.js +134 -43
  50. package/src/internal/document-model.js.map +1 -1
  51. package/src/internal/field-metadata.js +2 -1
  52. package/src/internal/field-metadata.js.map +1 -1
  53. package/src/internal/form-capabilities.js +1 -1
  54. package/src/{location-CPX7oj0o.js → location-CMNGO3lU.js} +2 -2
  55. package/src/{location-CPX7oj0o.js.map → location-CMNGO3lU.js.map} +1 -1
  56. package/src/{metadata-BEZPWh-3.js → metadata-UzZmjwxM.js} +2 -2
  57. package/src/{metadata-BEZPWh-3.js.map → metadata-UzZmjwxM.js.map} +1 -1
  58. package/src/{models-C9kF9JlQ.js → models-5j67LMqW.js} +4 -4
  59. package/src/{models-C9kF9JlQ.js.map → models-5j67LMqW.js.map} +1 -1
  60. package/src/{models-ChRxBChy.js → models-VmGmG19-.js} +42 -130
  61. package/src/models-VmGmG19-.js.map +1 -0
  62. package/src/runtime/delivery/DocumentRenderer.js +5 -1
  63. package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
  64. package/src/runtime/delivery/context.js +1 -1
  65. package/src/runtime/delivery/document-page.js +1 -5
  66. package/src/runtime/delivery/document-page.js.map +1 -1
  67. package/src/runtime/delivery/plugin.js +34 -5
  68. package/src/runtime/delivery/plugin.js.map +1 -1
  69. package/src/runtime/delivery/preview.d.ts +1 -1
  70. package/src/runtime/delivery/types.d.ts +1 -1
  71. package/src/runtime/delivery/useCmsDocumentSeo.d.ts +2 -1
  72. package/src/runtime/delivery/useCmsDocumentSeo.js +5 -4
  73. package/src/runtime/delivery/useCmsDocumentSeo.js.map +1 -1
  74. package/src/runtime/forms/document.js +2 -2
  75. package/src/runtime/forms/useCmsForm.js +2 -2
  76. package/src/runtime/installation.js +1 -1
  77. package/src/runtime/plugin.js +1 -1
  78. package/src/runtime/preview/CmsStudioPreviewMarker.js +18 -4
  79. package/src/runtime/preview/CmsStudioPreviewMarker.js.map +1 -1
  80. package/src/runtime/preview/connection.js +1 -1
  81. package/src/runtime/preview/controller.js +65 -74
  82. package/src/runtime/preview/controller.js.map +1 -1
  83. package/src/runtime/preview/overlay.js +85 -28
  84. package/src/runtime/preview/overlay.js.map +1 -1
  85. package/src/runtime/preview/plugin.client.js +4 -4
  86. package/src/runtime/preview/preview.css +50 -36
  87. package/src/runtime/preview/protocol.d.ts +11 -5
  88. package/src/runtime/preview/protocol.js +17 -5
  89. package/src/runtime/preview/protocol.js.map +1 -1
  90. package/src/runtime/preview/regions.js +142 -0
  91. package/src/runtime/preview/regions.js.map +1 -0
  92. package/src/runtime/preview/store.js +1 -1
  93. package/src/runtime/sitemap.js +9 -10
  94. package/src/runtime/sitemap.js.map +1 -1
  95. package/src/{scalars-B2lgGUnj.js → scalars-CVZqT3L0.js} +2 -6
  96. package/src/scalars-CVZqT3L0.js.map +1 -0
  97. package/src/{store-CCsjHaZm.js → store-PKKB8xa2.js} +49 -66
  98. package/src/store-PKKB8xa2.js.map +1 -0
  99. package/src/{types-DutFRtaG.d.ts → types-DZ0IV-Ow.d.ts} +14 -3
  100. package/studio/CreateDocumentDialog-vQ8hDs2C.js +253 -0
  101. package/studio/{documentPlanning-CDb31mnl.js → documentPlanning-Bx3W9KkD.js} +12054 -12085
  102. package/studio/{editor-Bzlh3zXt.js → editor-P2rB7Csp.js} +11228 -11927
  103. package/studio/host.css +1 -1
  104. package/studio/host.js +23595 -24903
  105. package/studio/rolldown-runtime-Dy4uBu1J.js +11 -0
  106. package/src/Configuration-BU-UyGoH.js.map +0 -1
  107. package/src/ContentTransfer-BhF9G56s.js +0 -57
  108. package/src/ContentTransfer-BhF9G56s.js.map +0 -1
  109. package/src/DocumentEngine-ClhFXW9M.js.map +0 -1
  110. package/src/Forms-DoB56hfe.js.map +0 -1
  111. package/src/S3MediaObjects-CR3p1WTg.js.map +0 -1
  112. package/src/dev-lifecycle-D3f9-upa.js.map +0 -1
  113. package/src/installation-fZtNxtoW.js.map +0 -1
  114. package/src/models-ChRxBChy.js.map +0 -1
  115. package/src/runtime/preview/targets.js +0 -101
  116. package/src/runtime/preview/targets.js.map +0 -1
  117. package/src/scalars-B2lgGUnj.js.map +0 -1
  118. package/src/store-CCsjHaZm.js.map +0 -1
  119. package/studio/CreateDocumentDialog-DJ8c0WZb.js +0 -256
  120. package/studio/dom-to-image-more.min-D6jGGdrW.js +0 -877
  121. package/studio/rolldown-runtime-B0aSnxlc.js +0 -20
@@ -64,10 +64,10 @@ function describeContentDiff(local, remote) {
64
64
  function describeContentDiffResult(comparison) {
65
65
  const lines = [];
66
66
  for (const change of comparison.changes) {
67
- if (change.markdownChanged && change.local) lines.push(createTwoFilesPatch(`remote/${change.sourcePath}`, `local/${change.sourcePath}`, change.target?.markdown ?? "", change.local.markdown).trimEnd());
68
- if (change.publicationChanged && change.local && change.target) lines.push(`Publication ${change.sourcePath}: CMS ${change.target.published ? "published" : "draft"}, local ${change.local.published ? "published (use --publish to apply)" : "draft (import keeps existing publication)"}`);
67
+ if (change.markdownChanged && change.local) lines.push(createTwoFilesPatch(`remote/${change.filePath}`, `local/${change.filePath}`, change.target?.markdown ?? "", change.local.markdown).trimEnd());
68
+ if (change.publicationChanged && change.local && change.target) lines.push(`Publication ${change.filePath}: CMS ${change.target.published ? "published" : "draft"}, local ${change.local.published ? "published (use --publish to apply)" : "draft (use --publish to apply)"}`);
69
69
  }
70
- for (const source of comparison.targetOnly) lines.push(`Remote only: ${source.sourcePath}`);
70
+ for (const source of comparison.targetOnly) lines.push(`Remote only: ${source.identity ? `${source.identity.collection}/${source.identity.documentId}` : "filePath" in source ? source.filePath : "document"}`);
71
71
  return {
72
72
  lines,
73
73
  changed: comparison.changes.length
@@ -79,10 +79,11 @@ function printPlan(value) {
79
79
  ["create", value.creates],
80
80
  ["update", value.updates],
81
81
  ["publish", value.publications],
82
+ ["unpublish", value.unpublications],
82
83
  ["unchanged", value.unchanged],
83
84
  ["conflict", value.conflicts]
84
- ]) for (const entry of entries) yield* Console.log(`${action.padEnd(9)} ${entry.sourcePath}`);
85
- for (const issue of value.issues) yield* Console.error(`${issue.severity}: ${issue.sourcePath ?? ""} ${issue.message}`);
85
+ ]) for (const entry of entries) yield* Console.log(`${action.padEnd(9)} ${entry.filePath}`);
86
+ for (const issue of value.issues) yield* Console.error(`${issue.severity}: ${issue.documentId ?? ""} ${issue.message}`);
86
87
  yield* Console.log(value.valid ? `Ready at generation ${value.generation}` : "Plan has conflicts or validation errors.");
87
88
  });
88
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","names":[],"sources":["../../../../src/cli/content.ts"],"sourcesContent":["import type { ContentSource } from '@internal/protocol/ContentTransfer'\nimport { CmsContentError, createCmsContentClient, diffCmsContentSources, readCmsContentDirectory } from '../Content'\nimport type { CmsContentDiff, CmsContentPlan } from '../Content'\nimport { Config, Console, Effect, Option, Redacted } from 'effect'\nimport { CliError, Prompt } from 'effect/unstable/cli'\nimport { createTwoFilesPatch } from 'diff'\n\nexport interface ConnectionOptions {\n readonly url: string\n readonly email: string\n}\n\nexport interface ImportOptions {\n readonly overwrite: boolean\n readonly publish: boolean\n}\n\nfunction userError(message: string) {\n return new CliError.UserError({ cause: new Error(message), userMessage: message })\n}\n\nconst client = Effect.fn('CmsCli.content.client')(function* (options: ConnectionOptions) {\n const baseUrl =\n options.url ||\n (yield* Config.String('CMS_URL').pipe(Config.withDefault(''))) ||\n (yield* Prompt.String({ message: 'CMS URL' }))\n\n const email =\n options.email ||\n (yield* Config.String('CMS_EMAIL').pipe(Config.withDefault(''))) ||\n (yield* Prompt.String({ message: 'Administrator email' }))\n\n if (!baseUrl || !email) return yield* userError('CMS URL and administrator email are required.')\n const configured = yield* Config.Redacted('CMS_PASSWORD').pipe(Config.option)\n\n const password = Option.isSome(configured)\n ? Redacted.value(configured.value)\n : Redacted.value(yield* Prompt.Password({ message: `Password for ${email} at ${baseUrl}` }))\n\n return yield* attempt(() => createCmsContentClient({ baseUrl, credentials: { email, password } }))\n})\n\nexport const readSources = Effect.fn('CmsCli.content.readSources')(function* (directory: string) {\n return (yield* attempt(() => readCmsContentDirectory(directory))).sources\n})\n\nexport const exportContent = Effect.fn('CmsCli.content.export')(function* (\n connection: ConnectionOptions,\n directory: string,\n) {\n const content = yield* client(connection)\n const source = yield* attempt(() => content.export({ directory }))\n yield* Console.log(`Exported ${source.sources.length} documents to ${directory}`)\n})\n\nconst preparePlan = Effect.fn('CmsCli.content.preparePlan')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n const source = yield* attempt(() => readCmsContentDirectory(directory))\n const content = yield* client(connection)\n const plan = yield* attempt(() => content.plan(source, options))\n yield* printPlan(plan)\n\n if (!plan.valid) return yield* userError('Content plan is not ready to apply.')\n\n return { content, plan }\n})\n\nexport const planContent = Effect.fn('CmsCli.content.planCommand')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n yield* preparePlan(connection, directory, options)\n})\n\nexport const applyContent = Effect.fn('CmsCli.content.apply')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n const { content, plan } = yield* preparePlan(connection, directory, options)\n const result = yield* attempt(() => content.apply(plan))\n yield* Console.log(\n `Applied: ${result.created} created, ${result.updated} updated, ${result.published} published, ${result.unchanged} unchanged.`,\n )\n})\n\nexport const diffContent = Effect.fn('CmsCli.content.diff')(function* (\n connection: ConnectionOptions,\n directory: string,\n) {\n const source = yield* attempt(() => readCmsContentDirectory(directory))\n const content = yield* client(connection)\n const comparison = describeContentDiffResult(yield* attempt(() => content.diff(source)))\n\n for (const line of comparison.lines) yield* Console.log(line)\n\n yield* Console.log(\n `${comparison.changed} local document${comparison.changed === 1 ? ' differs' : 's differ'} from the CMS.`,\n )\n})\n\nexport function describeContentDiff(local: ReadonlyArray<ContentSource>, remote: ReadonlyArray<ContentSource>) {\n return describeContentDiffResult(diffCmsContentSources(local, remote))\n}\n\nfunction describeContentDiffResult(comparison: CmsContentDiff) {\n const lines: string[] = []\n\n for (const change of comparison.changes) {\n if (change.markdownChanged && change.local) {\n lines.push(\n createTwoFilesPatch(\n `remote/${change.sourcePath}`,\n `local/${change.sourcePath}`,\n change.target?.markdown ?? '',\n change.local.markdown,\n ).trimEnd(),\n )\n }\n\n if (change.publicationChanged && change.local && change.target)\n lines.push(\n `Publication ${change.sourcePath}: CMS ${change.target.published ? 'published' : 'draft'}, local ${change.local.published ? 'published (use --publish to apply)' : 'draft (import keeps existing publication)'}`,\n )\n }\n\n for (const source of comparison.targetOnly) lines.push(`Remote only: ${source.sourcePath}`)\n\n return { lines, changed: comparison.changes.length }\n}\n\nfunction printPlan(value: CmsContentPlan) {\n return Effect.gen(function* () {\n for (const [action, entries] of [\n ['create', value.creates],\n ['update', value.updates],\n ['publish', value.publications],\n ['unchanged', value.unchanged],\n ['conflict', value.conflicts],\n ] as const)\n for (const entry of entries) yield* Console.log(`${action.padEnd(9)} ${entry.sourcePath}`)\n\n for (const issue of value.issues)\n yield* Console.error(`${issue.severity}: ${issue.sourcePath ?? ''} ${issue.message}`)\n\n yield* Console.log(\n value.valid ? `Ready at generation ${value.generation}` : 'Plan has conflicts or validation errors.',\n )\n })\n}\n\nfunction attempt<Value>(operation: () => Value | PromiseLike<Value>) {\n return Effect.tryPromise({\n try: () => Promise.resolve(operation()),\n catch: (cause) => {\n const message = cause instanceof CmsContentError ? `${cause.code}: ${cause.message}` : String(cause)\n\n return userError(message)\n },\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"content.js","names":[],"sources":["../../../../src/cli/content.ts"],"sourcesContent":["import type { ContentSource } from '@internal/protocol/ContentTransfer'\nimport { CmsContentError, createCmsContentClient, diffCmsContentSources, readCmsContentDirectory } from '../Content'\nimport type { CmsContentDiff, CmsContentPlan } from '../Content'\nimport { Config, Console, Effect, Option, Redacted } from 'effect'\nimport { CliError, Prompt } from 'effect/unstable/cli'\nimport { createTwoFilesPatch } from 'diff'\n\nexport interface ConnectionOptions {\n readonly url: string\n readonly email: string\n}\n\nexport interface ImportOptions {\n readonly overwrite: boolean\n readonly publish: boolean\n}\n\nfunction userError(message: string) {\n return new CliError.UserError({ cause: new Error(message), userMessage: message })\n}\n\nconst client = Effect.fn('CmsCli.content.client')(function* (options: ConnectionOptions) {\n const baseUrl =\n options.url ||\n (yield* Config.String('CMS_URL').pipe(Config.withDefault(''))) ||\n (yield* Prompt.String({ message: 'CMS URL' }))\n\n const email =\n options.email ||\n (yield* Config.String('CMS_EMAIL').pipe(Config.withDefault(''))) ||\n (yield* Prompt.String({ message: 'Administrator email' }))\n\n if (!baseUrl || !email) return yield* userError('CMS URL and administrator email are required.')\n const configured = yield* Config.Redacted('CMS_PASSWORD').pipe(Config.option)\n\n const password = Option.isSome(configured)\n ? Redacted.value(configured.value)\n : Redacted.value(yield* Prompt.Password({ message: `Password for ${email} at ${baseUrl}` }))\n\n return yield* attempt(() => createCmsContentClient({ baseUrl, credentials: { email, password } }))\n})\n\nexport const readSources = Effect.fn('CmsCli.content.readSources')(function* (directory: string) {\n return (yield* attempt(() => readCmsContentDirectory(directory))).sources\n})\n\nexport const exportContent = Effect.fn('CmsCli.content.export')(function* (\n connection: ConnectionOptions,\n directory: string,\n) {\n const content = yield* client(connection)\n const source = yield* attempt(() => content.export({ directory }))\n yield* Console.log(`Exported ${source.sources.length} documents to ${directory}`)\n})\n\nconst preparePlan = Effect.fn('CmsCli.content.preparePlan')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n const source = yield* attempt(() => readCmsContentDirectory(directory))\n const content = yield* client(connection)\n const plan = yield* attempt(() => content.plan(source, options))\n yield* printPlan(plan)\n\n if (!plan.valid) return yield* userError('Content plan is not ready to apply.')\n\n return { content, plan }\n})\n\nexport const planContent = Effect.fn('CmsCli.content.planCommand')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n yield* preparePlan(connection, directory, options)\n})\n\nexport const applyContent = Effect.fn('CmsCli.content.apply')(function* (\n connection: ConnectionOptions,\n directory: string,\n options: ImportOptions,\n) {\n const { content, plan } = yield* preparePlan(connection, directory, options)\n const result = yield* attempt(() => content.apply(plan))\n yield* Console.log(\n `Applied: ${result.created} created, ${result.updated} updated, ${result.published} published, ${result.unchanged} unchanged.`,\n )\n})\n\nexport const diffContent = Effect.fn('CmsCli.content.diff')(function* (\n connection: ConnectionOptions,\n directory: string,\n) {\n const source = yield* attempt(() => readCmsContentDirectory(directory))\n const content = yield* client(connection)\n const comparison = describeContentDiffResult(yield* attempt(() => content.diff(source)))\n\n for (const line of comparison.lines) yield* Console.log(line)\n\n yield* Console.log(\n `${comparison.changed} local document${comparison.changed === 1 ? ' differs' : 's differ'} from the CMS.`,\n )\n})\n\nexport function describeContentDiff(local: ReadonlyArray<ContentSource>, remote: ReadonlyArray<ContentSource>) {\n return describeContentDiffResult(diffCmsContentSources(local, remote))\n}\n\nfunction describeContentDiffResult(comparison: CmsContentDiff) {\n const lines: string[] = []\n\n for (const change of comparison.changes) {\n if (change.markdownChanged && change.local) {\n lines.push(\n createTwoFilesPatch(\n `remote/${change.filePath}`,\n `local/${change.filePath}`,\n change.target?.markdown ?? '',\n change.local.markdown,\n ).trimEnd(),\n )\n }\n\n if (change.publicationChanged && change.local && change.target)\n lines.push(\n `Publication ${change.filePath}: CMS ${change.target.published ? 'published' : 'draft'}, local ${change.local.published ? 'published (use --publish to apply)' : 'draft (use --publish to apply)'}`,\n )\n }\n\n for (const source of comparison.targetOnly)\n lines.push(\n `Remote only: ${source.identity ? `${source.identity.collection}/${source.identity.documentId}` : 'filePath' in source ? source.filePath : 'document'}`,\n )\n\n return { lines, changed: comparison.changes.length }\n}\n\nfunction printPlan(value: CmsContentPlan) {\n return Effect.gen(function* () {\n for (const [action, entries] of [\n ['create', value.creates],\n ['update', value.updates],\n ['publish', value.publications],\n ['unpublish', value.unpublications],\n ['unchanged', value.unchanged],\n ['conflict', value.conflicts],\n ] as const)\n for (const entry of entries) yield* Console.log(`${action.padEnd(9)} ${entry.filePath}`)\n\n for (const issue of value.issues)\n yield* Console.error(`${issue.severity}: ${issue.documentId ?? ''} ${issue.message}`)\n\n yield* Console.log(\n value.valid ? `Ready at generation ${value.generation}` : 'Plan has conflicts or validation errors.',\n )\n })\n}\n\nfunction attempt<Value>(operation: () => Value | PromiseLike<Value>) {\n return Effect.tryPromise({\n try: () => Promise.resolve(operation()),\n catch: (cause) => {\n const message = cause instanceof CmsContentError ? `${cause.code}: ${cause.message}` : String(cause)\n\n return userError(message)\n },\n })\n}\n"],"mappings":";;;;;;AAiBA,SAAS,UAAU,SAAiB;CAClC,OAAO,IAAI,SAAS,UAAU;EAAE,OAAO,IAAI,MAAM,OAAO;EAAG,aAAa;CAAQ,CAAC;AACnF;AAEA,MAAM,SAAS,OAAO,GAAG,uBAAuB,CAAC,CAAC,WAAW,SAA4B;CACvF,MAAM,UACJ,QAAQ,QACP,OAAO,OAAO,OAAO,SAAS,CAAC,CAAC,KAAK,OAAO,YAAY,EAAE,CAAC,OAC3D,OAAO,OAAO,OAAO,EAAE,SAAS,UAAU,CAAC;CAE9C,MAAM,QACJ,QAAQ,UACP,OAAO,OAAO,OAAO,WAAW,CAAC,CAAC,KAAK,OAAO,YAAY,EAAE,CAAC,OAC7D,OAAO,OAAO,OAAO,EAAE,SAAS,sBAAsB,CAAC;CAE1D,IAAI,CAAC,WAAW,CAAC,OAAO,OAAO,OAAO,UAAU,+CAA+C;CAC/F,MAAM,aAAa,OAAO,OAAO,SAAS,cAAc,CAAC,CAAC,KAAK,OAAO,MAAM;CAE5E,MAAM,WAAW,OAAO,OAAO,UAAU,IACrC,SAAS,MAAM,WAAW,KAAK,IAC/B,SAAS,MAAM,OAAO,OAAO,SAAS,EAAE,SAAS,gBAAgB,MAAM,MAAM,UAAU,CAAC,CAAC;CAE7F,OAAO,OAAO,cAAc,uBAAuB;EAAE;EAAS,aAAa;GAAE;GAAO;EAAS;CAAE,CAAC,CAAC;AACnG,CAAC;AAED,MAAa,cAAc,OAAO,GAAG,4BAA4B,CAAC,CAAC,WAAW,WAAmB;CAC/F,QAAQ,OAAO,cAAc,wBAAwB,SAAS,CAAC,EAAC,CAAE;AACpE,CAAC;AAED,MAAa,gBAAgB,OAAO,GAAG,uBAAuB,CAAC,CAAC,WAC9D,YACA,WACA;CACA,MAAM,UAAU,OAAO,OAAO,UAAU;CACxC,MAAM,SAAS,OAAO,cAAc,QAAQ,OAAO,EAAE,UAAU,CAAC,CAAC;CACjE,OAAO,QAAQ,IAAI,YAAY,OAAO,QAAQ,OAAO,gBAAgB,WAAW;AAClF,CAAC;AAED,MAAM,cAAc,OAAO,GAAG,4BAA4B,CAAC,CAAC,WAC1D,YACA,WACA,SACA;CACA,MAAM,SAAS,OAAO,cAAc,wBAAwB,SAAS,CAAC;CACtE,MAAM,UAAU,OAAO,OAAO,UAAU;CACxC,MAAM,OAAO,OAAO,cAAc,QAAQ,KAAK,QAAQ,OAAO,CAAC;CAC/D,OAAO,UAAU,IAAI;CAErB,IAAI,CAAC,KAAK,OAAO,OAAO,OAAO,UAAU,qCAAqC;CAE9E,OAAO;EAAE;EAAS;CAAK;AACzB,CAAC;AAED,MAAa,cAAc,OAAO,GAAG,4BAA4B,CAAC,CAAC,WACjE,YACA,WACA,SACA;CACA,OAAO,YAAY,YAAY,WAAW,OAAO;AACnD,CAAC;AAED,MAAa,eAAe,OAAO,GAAG,sBAAsB,CAAC,CAAC,WAC5D,YACA,WACA,SACA;CACA,MAAM,EAAE,SAAS,SAAS,OAAO,YAAY,YAAY,WAAW,OAAO;CAC3E,MAAM,SAAS,OAAO,cAAc,QAAQ,MAAM,IAAI,CAAC;CACvD,OAAO,QAAQ,IACb,YAAY,OAAO,QAAQ,YAAY,OAAO,QAAQ,YAAY,OAAO,UAAU,cAAc,OAAO,UAAU,YACpH;AACF,CAAC;AAED,MAAa,cAAc,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAC1D,YACA,WACA;CACA,MAAM,SAAS,OAAO,cAAc,wBAAwB,SAAS,CAAC;CACtE,MAAM,UAAU,OAAO,OAAO,UAAU;CACxC,MAAM,aAAa,0BAA0B,OAAO,cAAc,QAAQ,KAAK,MAAM,CAAC,CAAC;CAEvF,KAAK,MAAM,QAAQ,WAAW,OAAO,OAAO,QAAQ,IAAI,IAAI;CAE5D,OAAO,QAAQ,IACb,GAAG,WAAW,QAAQ,iBAAiB,WAAW,YAAY,IAAI,aAAa,WAAW,eAC5F;AACF,CAAC;AAED,SAAgB,oBAAoB,OAAqC,QAAsC;CAC7G,OAAO,0BAA0B,sBAAsB,OAAO,MAAM,CAAC;AACvE;AAEA,SAAS,0BAA0B,YAA4B;CAC7D,MAAM,QAAkB,CAAC;CAEzB,KAAK,MAAM,UAAU,WAAW,SAAS;EACvC,IAAI,OAAO,mBAAmB,OAAO,OACnC,MAAM,KACJ,oBACE,UAAU,OAAO,YACjB,SAAS,OAAO,YAChB,OAAO,QAAQ,YAAY,IAC3B,OAAO,MAAM,QACf,CAAC,CAAC,QAAQ,CACZ;EAGF,IAAI,OAAO,sBAAsB,OAAO,SAAS,OAAO,QACtD,MAAM,KACJ,eAAe,OAAO,SAAS,QAAQ,OAAO,OAAO,YAAY,cAAc,QAAQ,UAAU,OAAO,MAAM,YAAY,uCAAuC,kCACnK;CACJ;CAEA,KAAK,MAAM,UAAU,WAAW,YAC9B,MAAM,KACJ,gBAAgB,OAAO,WAAW,GAAG,OAAO,SAAS,WAAW,GAAG,OAAO,SAAS,eAAe,cAAc,SAAS,OAAO,WAAW,YAC7I;CAEF,OAAO;EAAE;EAAO,SAAS,WAAW,QAAQ;CAAO;AACrD;AAEA,SAAS,UAAU,OAAuB;CACxC,OAAO,OAAO,IAAI,aAAa;EAC7B,KAAK,MAAM,CAAC,QAAQ,YAAY;GAC9B,CAAC,UAAU,MAAM,OAAO;GACxB,CAAC,UAAU,MAAM,OAAO;GACxB,CAAC,WAAW,MAAM,YAAY;GAC9B,CAAC,aAAa,MAAM,cAAc;GAClC,CAAC,aAAa,MAAM,SAAS;GAC7B,CAAC,YAAY,MAAM,SAAS;EAC9B,GACE,KAAK,MAAM,SAAS,SAAS,OAAO,QAAQ,IAAI,GAAG,OAAO,OAAO,CAAC,EAAE,GAAG,MAAM,UAAU;EAEzF,KAAK,MAAM,SAAS,MAAM,QACxB,OAAO,QAAQ,MAAM,GAAG,MAAM,SAAS,IAAI,MAAM,cAAc,GAAG,GAAG,MAAM,SAAS;EAEtF,OAAO,QAAQ,IACb,MAAM,QAAQ,uBAAuB,MAAM,eAAe,0CAC5D;CACF,CAAC;AACH;AAEA,SAAS,QAAe,WAA6C;CACnE,OAAO,OAAO,WAAW;EACvB,WAAW,QAAQ,QAAQ,UAAU,CAAC;EACtC,QAAQ,UAAU;GAGhB,OAAO,UAFS,iBAAiB,kBAAkB,GAAG,MAAM,KAAK,IAAI,MAAM,YAAY,OAAO,KAAK,CAE3E;EAC1B;CACF,CAAC;AACH"}
package/src/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { applyContent, diffContent, exportContent, planContent } from "./cli/content.js";
2
- import { i as resetCmsDevelopment, n as doctorCmsDevelopment, r as loadCmsProjectEnvironment, t as bootstrapCmsDevelopment } from "./dev-lifecycle-D3f9-upa.js";
2
+ import { o as renderConfigurationReport } from "./installation-BoG8E3nJ.js";
3
+ import { a as resetCmsDevelopment, i as loadCmsProjectEnvironment, n as checkCmsConfiguration, r as doctorCmsDevelopment, t as bootstrapCmsDevelopment } from "./dev-lifecycle-DdBluSiR.js";
3
4
  import { diagnosticFromCause, renderDiagnostic } from "./internal/diagnostics.js";
4
5
  import { Config, Console, Effect, Layer, Match, Option, Redacted, Runtime, Schema } from "effect";
5
6
  import { NodeChildProcessSpawner, NodeCrypto, NodeFileSystem, NodePath, NodeRuntime, NodeStdio, NodeTerminal } from "@effect/platform-node-shared";
@@ -7,7 +8,7 @@ import { FetchHttpClient } from "effect/unstable/http";
7
8
  import { Argument, CliError, Command, Flag, Prompt } from "effect/unstable/cli";
8
9
 
9
10
  //#region package.json
10
- var version = "0.2.0-beta.3";
11
+ var version = "0.2.0-beta.5";
11
12
 
12
13
  //#endregion
13
14
  //#region src/cli.ts
@@ -74,6 +75,14 @@ const content = Command.make("content").pipe(Command.withSubcommands([
74
75
  planCommand,
75
76
  applyCommand
76
77
  ]));
78
+ const configurationCheckCommand = Command.make("check", {}, () => Effect.gen(function* () {
79
+ const options = yield* root;
80
+ const report = yield* attempt("configuration.check", options, () => checkCmsConfiguration(options.rootDirectory, options.envFile || void 0, options.verbose));
81
+ if (options.json) yield* Console.log(JSON.stringify(report));
82
+ else yield* Console.log(renderConfigurationReport(report));
83
+ if (!report.compatible) return yield* options.json ? new JsonCommandFailed({}) : cliError("The candidate CMS configuration is incompatible with stored content.");
84
+ })).pipe(Command.withDescription("Compare the candidate configuration with the accepted catalog and stored content"));
85
+ const configuration = Command.make("configuration").pipe(Command.withSubcommands([configurationCheckCommand]));
77
86
  const full = Flag.Boolean("full").pipe(Flag.withDefault(false));
78
87
  const contentDirectory = Flag.String("content").pipe(Flag.withDefault(""));
79
88
  const administratorName = Flag.String("name").pipe(Flag.withDefault(""));
@@ -179,7 +188,11 @@ function commandFailure(phase, options, cause) {
179
188
  return yield* new JsonCommandFailed({});
180
189
  });
181
190
  }
182
- root.pipe(Command.withSubcommands([content, dev]), Command.run({ version }), Effect.provide(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer, NodeCrypto.layer, NodeTerminal.layer, NodeStdio.layer, NodeChildProcessSpawner.layer.pipe(Layer.provide(Layer.merge(NodeFileSystem.layer, NodePath.layer))), FetchHttpClient.layer)), NodeRuntime.runMain);
191
+ root.pipe(Command.withSubcommands([
192
+ configuration,
193
+ content,
194
+ dev
195
+ ]), Command.run({ version }), Effect.provide(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer, NodeCrypto.layer, NodeTerminal.layer, NodeStdio.layer, NodeChildProcessSpawner.layer.pipe(Layer.provide(Layer.merge(NodeFileSystem.layer, NodePath.layer))), FetchHttpClient.layer)), NodeRuntime.runMain);
183
196
 
184
197
  //#endregion
185
198
  export { };
package/src/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["packageManifest.version"],"sources":["../../../package.json","../../../src/cli.ts"],"sourcesContent":["","import {\n NodeChildProcessSpawner,\n NodeCrypto,\n NodeFileSystem,\n NodePath,\n NodeRuntime,\n NodeStdio,\n NodeTerminal,\n} from '@effect/platform-node-shared'\nimport { Config, Console, Effect, Layer, Match, Option, Redacted, Runtime, Schema } from 'effect'\nimport { Argument, CliError, Command, Flag, Prompt } from 'effect/unstable/cli'\nimport { FetchHttpClient } from 'effect/unstable/http'\nimport packageManifest from '../package.json' with { type: 'json' }\nimport { applyContent, diffContent, exportContent, planContent } from './cli/content'\nimport {\n bootstrapCmsDevelopment,\n doctorCmsDevelopment,\n loadCmsProjectEnvironment,\n resetCmsDevelopment,\n} from './internal/dev-lifecycle'\nimport { diagnosticFromCause, renderDiagnostic } from './internal/diagnostics'\n\nconst rootDirectory = Flag.String('root').pipe(Flag.withDefault('.'))\n\nconst envFile = Flag.String('env-file').pipe(Flag.withDefault(''))\n\nconst verbose = Flag.Boolean('verbose').pipe(Flag.withDefault(false))\n\nconst json = Flag.Boolean('json').pipe(Flag.withDefault(false))\n\nconst root = Command.make('cms').pipe(\n Command.withSharedFlags({\n url: Flag.String('url').pipe(Flag.withDefault('')),\n email: Flag.String('email').pipe(Flag.withDefault('')),\n rootDirectory,\n envFile,\n verbose,\n json,\n }),\n)\n\nconst directory = Argument.String('directory')\n\nconst overwrite = Flag.Boolean('overwrite').pipe(Flag.withDefault(false))\n\nconst publish = Flag.Boolean('publish').pipe(Flag.withDefault(false))\n\nconst exportCommand = Command.make('export', { directory }, ({ directory }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* exportContent({ url, email }, directory)\n }),\n).pipe(Command.withDescription('Export authored Markdown from a CMS installation'))\n\nconst diffCommand = Command.make('diff', { directory }, ({ directory }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* diffContent({ url, email }, directory)\n }),\n).pipe(Command.withDescription('Compare local Markdown with the current CMS content'))\n\nconst planCommand = Command.make('plan', { directory, overwrite, publish }, ({ directory, overwrite, publish }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* planContent({ url, email }, directory, { overwrite, publish })\n }),\n).pipe(Command.withDescription('Preview content changes without writing to the CMS'))\n\nconst applyCommand = Command.make('apply', { directory, overwrite, publish }, ({ directory, overwrite, publish }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* applyContent({ url, email }, directory, { overwrite, publish })\n }),\n).pipe(Command.withDescription('Apply a validated content plan to the CMS'))\n\nconst content = Command.make('content').pipe(\n Command.withSubcommands([exportCommand, diffCommand, planCommand, applyCommand]),\n)\n\nconst full = Flag.Boolean('full').pipe(Flag.withDefault(false))\n\nconst contentDirectory = Flag.String('content').pipe(Flag.withDefault(''))\n\nconst administratorName = Flag.String('name').pipe(Flag.withDefault(''))\n\nconst database = Flag.Boolean('database').pipe(Flag.withDefault(false))\n\nconst media = Flag.Boolean('media').pipe(Flag.withDefault(false))\n\nconst bootstrap = Flag.Boolean('bootstrap').pipe(Flag.withDefault(false))\n\nconst yes = Flag.Boolean('yes').pipe(Flag.withDefault(false))\n\nconst doctorCommand = Command.make('doctor', { full }, ({ full }) =>\n Effect.gen(function* () {\n const options = yield* root\n\n const report = yield* attempt('doctor.configuration', options, () =>\n doctorCmsDevelopment(options.rootDirectory, full, options.envFile || undefined),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n yield* Console.log(JSON.stringify(report))\n } else\n for (const check of report.checks) {\n const icon = Match.value(check.status).pipe(\n Match.when('pass', () => '✓'),\n Match.when('fail', () => '✗'),\n Match.when('not-verified', () => '−'),\n Match.exhaustive,\n )\n\n yield* Console.log(`${icon} ${check.label}${check.detail ? `\\n\\n ${check.detail}` : ''}`)\n }\n\n if (!report.ok)\n return yield* options.json ? new JsonCommandFailed({}) : cliError('One or more CMS development checks failed.')\n }),\n).pipe(Command.withDescription('Check local CMS configuration and infrastructure'))\n\nconst bootstrapCommand = Command.make(\n 'bootstrap',\n { contentDirectory, administratorName, publish },\n ({ contentDirectory, administratorName, publish }) =>\n Effect.gen(function* () {\n const options = yield* root\n yield* attempt('bootstrap.environment', options, () =>\n loadCmsProjectEnvironment(options.rootDirectory, options.envFile || undefined),\n )\n\n const administrator = yield* administratorOptions(\n administratorName,\n contentDirectory,\n publish,\n options,\n 'bootstrap.credentials',\n )\n\n const result = yield* attempt('bootstrap.installation', options, () =>\n bootstrapCmsDevelopment({\n rootDir: options.rootDirectory,\n envFile: options.envFile || undefined,\n verbose: options.verbose,\n ...administrator,\n }),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n yield* Console.log(JSON.stringify(result))\n } else\n yield* Console.log(\n `Bootstrap complete: administrator ${result.administrator}${result.contentApplied ? ', content applied' : ''}.`,\n )\n }),\n).pipe(Command.withDescription('Provision and initialize a local CMS installation'))\n\nconst resetCommand = Command.make(\n 'reset',\n { bootstrap, contentDirectory, database, media, publish, yes },\n ({ bootstrap, contentDirectory, database, media, publish, yes }) =>\n Effect.gen(function* () {\n const options = yield* root\n\n if (!database && !media)\n return yield* commandFailure('reset.arguments', options, new Error('Choose --database, --media, or both.'))\n\n if (bootstrap && yes)\n yield* attempt('reset.environment', options, () =>\n loadCmsProjectEnvironment(options.rootDirectory, options.envFile || undefined),\n )\n\n const administrator =\n bootstrap && yes\n ? yield* administratorOptions('', contentDirectory, publish, options, 'reset.credentials')\n : undefined\n\n const result = yield* attempt('reset.installation', options, () =>\n resetCmsDevelopment({\n rootDir: options.rootDirectory,\n envFile: options.envFile || undefined,\n database,\n media,\n yes,\n verbose: options.verbose,\n bootstrap: administrator,\n }),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n return yield* Console.log(JSON.stringify(result))\n }\n\n for (const target of result.targets)\n yield* Console.log(`${result.executed ? '✓ Reset' : 'Would reset'} ${target}`)\n\n if (!result.executed) yield* Console.log('Dry run only. Add --yes to execute these exact targets.')\n }),\n).pipe(Command.withDescription('Reset CMS-owned local data with a dry-run default'))\n\nconst dev = Command.make('dev').pipe(Command.withSubcommands([doctorCommand, bootstrapCommand, resetCommand]))\n\nconst administratorOptions = Effect.fn('CmsCli.dev.administratorOptions')(function* (\n name: string,\n content: string,\n publishContent: boolean,\n options: { readonly json: boolean; readonly verbose: boolean },\n phase: string,\n) {\n const email = yield* Config.String('CMS_EMAIL').pipe(Config.withDefault(''))\n const configuredPassword = yield* Config.Redacted('CMS_PASSWORD').pipe(Config.option)\n\n if (!email) return yield* commandFailure(phase, options, new Error('CMS_EMAIL is required.'))\n\n if (Option.isNone(configuredPassword) && options.json)\n return yield* commandFailure(phase, options, new Error('CMS_PASSWORD is required.'))\n\n const password = Option.isSome(configuredPassword)\n ? Redacted.value(configuredPassword.value)\n : Redacted.value(yield* Prompt.Password({ message: `Password for ${email}` }))\n\n if (!password) return yield* commandFailure(phase, options, new Error('CMS_PASSWORD is required.'))\n\n return {\n content: content || undefined,\n email,\n name: name || (yield* Config.String('CMS_NAME').pipe(Config.withDefault('Administrator'))),\n password,\n publish: publishContent,\n }\n})\n\nfunction cliError(message: string) {\n return new CliError.UserError({ cause: new Error(message), userMessage: message })\n}\n\nclass CliOperationFailed extends Schema.TaggedError<CliOperationFailed>()('CliOperationFailed', {\n cause: Schema.Defect(),\n}) {}\n\nclass JsonCommandFailed extends Schema.TaggedError<JsonCommandFailed>()('JsonCommandFailed', {}) {\n override readonly [Runtime.errorExitCode] = 1\n override [Runtime.errorReported] = false\n}\n\nfunction attempt<Value>(\n phase: string,\n options: { readonly json: boolean; readonly verbose: boolean },\n operation: () => Value | PromiseLike<Value>,\n) {\n return Effect.tryPromise({\n try: () => Promise.resolve(operation()),\n catch: (cause) => new CliOperationFailed({ cause }),\n }).pipe(Effect.catch((failure) => commandFailure(phase, options, failure.cause)))\n}\n\nfunction commandFailure(phase: string, options: { readonly json: boolean; readonly verbose: boolean }, cause: unknown) {\n return Effect.gen(function* () {\n const diagnostic = diagnosticFromCause(phase, cause)\n\n if (!options.json) return yield* cliError(renderDiagnostic(diagnostic, options.verbose))\n\n const { details: _details, ...output } = diagnostic\n\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- CLI JSON is an intentionally stable plain object.\n yield* Console.log(JSON.stringify(output))\n\n return yield* new JsonCommandFailed({})\n })\n}\n\nroot.pipe(\n Command.withSubcommands([content, dev]),\n Command.run({ version: packageManifest.version }),\n Effect.provide(\n Layer.mergeAll(\n NodeFileSystem.layer,\n NodePath.layer,\n NodeCrypto.layer,\n NodeTerminal.layer,\n NodeStdio.layer,\n NodeChildProcessSpawner.layer.pipe(Layer.provide(Layer.merge(NodeFileSystem.layer, NodePath.layer))),\n FetchHttpClient.layer,\n ),\n ),\n NodeRuntime.runMain,\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["packageManifest.version"],"sources":["../../../package.json","../../../src/cli.ts"],"sourcesContent":["","import {\n NodeChildProcessSpawner,\n NodeCrypto,\n NodeFileSystem,\n NodePath,\n NodeRuntime,\n NodeStdio,\n NodeTerminal,\n} from '@effect/platform-node-shared'\nimport { Config, Console, Effect, Layer, Match, Option, Redacted, Runtime, Schema } from 'effect'\nimport { Argument, CliError, Command, Flag, Prompt } from 'effect/unstable/cli'\nimport { FetchHttpClient } from 'effect/unstable/http'\nimport packageManifest from '../package.json' with { type: 'json' }\nimport { applyContent, diffContent, exportContent, planContent } from './cli/content'\nimport {\n bootstrapCmsDevelopment,\n checkCmsConfiguration,\n doctorCmsDevelopment,\n loadCmsProjectEnvironment,\n resetCmsDevelopment,\n} from './internal/dev-lifecycle'\nimport { diagnosticFromCause, renderDiagnostic } from './internal/diagnostics'\nimport { renderConfigurationReport } from '@internal/server/ConfigurationChanges'\n\nconst rootDirectory = Flag.String('root').pipe(Flag.withDefault('.'))\n\nconst envFile = Flag.String('env-file').pipe(Flag.withDefault(''))\n\nconst verbose = Flag.Boolean('verbose').pipe(Flag.withDefault(false))\n\nconst json = Flag.Boolean('json').pipe(Flag.withDefault(false))\n\nconst root = Command.make('cms').pipe(\n Command.withSharedFlags({\n url: Flag.String('url').pipe(Flag.withDefault('')),\n email: Flag.String('email').pipe(Flag.withDefault('')),\n rootDirectory,\n envFile,\n verbose,\n json,\n }),\n)\n\nconst directory = Argument.String('directory')\n\nconst overwrite = Flag.Boolean('overwrite').pipe(Flag.withDefault(false))\n\nconst publish = Flag.Boolean('publish').pipe(Flag.withDefault(false))\n\nconst exportCommand = Command.make('export', { directory }, ({ directory }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* exportContent({ url, email }, directory)\n }),\n).pipe(Command.withDescription('Export authored Markdown from a CMS installation'))\n\nconst diffCommand = Command.make('diff', { directory }, ({ directory }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* diffContent({ url, email }, directory)\n }),\n).pipe(Command.withDescription('Compare local Markdown with the current CMS content'))\n\nconst planCommand = Command.make('plan', { directory, overwrite, publish }, ({ directory, overwrite, publish }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* planContent({ url, email }, directory, { overwrite, publish })\n }),\n).pipe(Command.withDescription('Preview content changes without writing to the CMS'))\n\nconst applyCommand = Command.make('apply', { directory, overwrite, publish }, ({ directory, overwrite, publish }) =>\n Effect.gen(function* () {\n const { url, email } = yield* root\n\n return yield* applyContent({ url, email }, directory, { overwrite, publish })\n }),\n).pipe(Command.withDescription('Apply a validated content plan to the CMS'))\n\nconst content = Command.make('content').pipe(\n Command.withSubcommands([exportCommand, diffCommand, planCommand, applyCommand]),\n)\n\nconst configurationCheckCommand = Command.make('check', {}, () =>\n Effect.gen(function* () {\n const options = yield* root\n\n const report = yield* attempt('configuration.check', options, () =>\n checkCmsConfiguration(options.rootDirectory, options.envFile || undefined, options.verbose),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- The report schema is the stable machine-readable CLI contract.\n yield* Console.log(JSON.stringify(report))\n } else yield* Console.log(renderConfigurationReport(report))\n\n if (!report.compatible)\n return yield* options.json\n ? new JsonCommandFailed({})\n : cliError('The candidate CMS configuration is incompatible with stored content.')\n }),\n).pipe(Command.withDescription('Compare the candidate configuration with the accepted catalog and stored content'))\n\nconst configuration = Command.make('configuration').pipe(Command.withSubcommands([configurationCheckCommand]))\n\nconst full = Flag.Boolean('full').pipe(Flag.withDefault(false))\n\nconst contentDirectory = Flag.String('content').pipe(Flag.withDefault(''))\n\nconst administratorName = Flag.String('name').pipe(Flag.withDefault(''))\n\nconst database = Flag.Boolean('database').pipe(Flag.withDefault(false))\n\nconst media = Flag.Boolean('media').pipe(Flag.withDefault(false))\n\nconst bootstrap = Flag.Boolean('bootstrap').pipe(Flag.withDefault(false))\n\nconst yes = Flag.Boolean('yes').pipe(Flag.withDefault(false))\n\nconst doctorCommand = Command.make('doctor', { full }, ({ full }) =>\n Effect.gen(function* () {\n const options = yield* root\n\n const report = yield* attempt('doctor.configuration', options, () =>\n doctorCmsDevelopment(options.rootDirectory, full, options.envFile || undefined),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n yield* Console.log(JSON.stringify(report))\n } else\n for (const check of report.checks) {\n const icon = Match.value(check.status).pipe(\n Match.when('pass', () => '✓'),\n Match.when('fail', () => '✗'),\n Match.when('not-verified', () => '−'),\n Match.exhaustive,\n )\n\n yield* Console.log(`${icon} ${check.label}${check.detail ? `\\n\\n ${check.detail}` : ''}`)\n }\n\n if (!report.ok)\n return yield* options.json ? new JsonCommandFailed({}) : cliError('One or more CMS development checks failed.')\n }),\n).pipe(Command.withDescription('Check local CMS configuration and infrastructure'))\n\nconst bootstrapCommand = Command.make(\n 'bootstrap',\n { contentDirectory, administratorName, publish },\n ({ contentDirectory, administratorName, publish }) =>\n Effect.gen(function* () {\n const options = yield* root\n yield* attempt('bootstrap.environment', options, () =>\n loadCmsProjectEnvironment(options.rootDirectory, options.envFile || undefined),\n )\n\n const administrator = yield* administratorOptions(\n administratorName,\n contentDirectory,\n publish,\n options,\n 'bootstrap.credentials',\n )\n\n const result = yield* attempt('bootstrap.installation', options, () =>\n bootstrapCmsDevelopment({\n rootDir: options.rootDirectory,\n envFile: options.envFile || undefined,\n verbose: options.verbose,\n ...administrator,\n }),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n yield* Console.log(JSON.stringify(result))\n } else\n yield* Console.log(\n `Bootstrap complete: administrator ${result.administrator}${result.contentApplied ? ', content applied' : ''}.`,\n )\n }),\n).pipe(Command.withDescription('Provision and initialize a local CMS installation'))\n\nconst resetCommand = Command.make(\n 'reset',\n { bootstrap, contentDirectory, database, media, publish, yes },\n ({ bootstrap, contentDirectory, database, media, publish, yes }) =>\n Effect.gen(function* () {\n const options = yield* root\n\n if (!database && !media)\n return yield* commandFailure('reset.arguments', options, new Error('Choose --database, --media, or both.'))\n\n if (bootstrap && yes)\n yield* attempt('reset.environment', options, () =>\n loadCmsProjectEnvironment(options.rootDirectory, options.envFile || undefined),\n )\n\n const administrator =\n bootstrap && yes\n ? yield* administratorOptions('', contentDirectory, publish, options, 'reset.credentials')\n : undefined\n\n const result = yield* attempt('reset.installation', options, () =>\n resetCmsDevelopment({\n rootDir: options.rootDirectory,\n envFile: options.envFile || undefined,\n database,\n media,\n yes,\n verbose: options.verbose,\n bootstrap: administrator,\n }),\n )\n\n if (options.json) {\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- This flag intentionally emits the report's exact JSON representation.\n return yield* Console.log(JSON.stringify(result))\n }\n\n for (const target of result.targets)\n yield* Console.log(`${result.executed ? '✓ Reset' : 'Would reset'} ${target}`)\n\n if (!result.executed) yield* Console.log('Dry run only. Add --yes to execute these exact targets.')\n }),\n).pipe(Command.withDescription('Reset CMS-owned local data with a dry-run default'))\n\nconst dev = Command.make('dev').pipe(Command.withSubcommands([doctorCommand, bootstrapCommand, resetCommand]))\n\nconst administratorOptions = Effect.fn('CmsCli.dev.administratorOptions')(function* (\n name: string,\n content: string,\n publishContent: boolean,\n options: { readonly json: boolean; readonly verbose: boolean },\n phase: string,\n) {\n const email = yield* Config.String('CMS_EMAIL').pipe(Config.withDefault(''))\n const configuredPassword = yield* Config.Redacted('CMS_PASSWORD').pipe(Config.option)\n\n if (!email) return yield* commandFailure(phase, options, new Error('CMS_EMAIL is required.'))\n\n if (Option.isNone(configuredPassword) && options.json)\n return yield* commandFailure(phase, options, new Error('CMS_PASSWORD is required.'))\n\n const password = Option.isSome(configuredPassword)\n ? Redacted.value(configuredPassword.value)\n : Redacted.value(yield* Prompt.Password({ message: `Password for ${email}` }))\n\n if (!password) return yield* commandFailure(phase, options, new Error('CMS_PASSWORD is required.'))\n\n return {\n content: content || undefined,\n email,\n name: name || (yield* Config.String('CMS_NAME').pipe(Config.withDefault('Administrator'))),\n password,\n publish: publishContent,\n }\n})\n\nfunction cliError(message: string) {\n return new CliError.UserError({ cause: new Error(message), userMessage: message })\n}\n\nclass CliOperationFailed extends Schema.TaggedError<CliOperationFailed>()('CliOperationFailed', {\n cause: Schema.Defect(),\n}) {}\n\nclass JsonCommandFailed extends Schema.TaggedError<JsonCommandFailed>()('JsonCommandFailed', {}) {\n override readonly [Runtime.errorExitCode] = 1\n override [Runtime.errorReported] = false\n}\n\nfunction attempt<Value>(\n phase: string,\n options: { readonly json: boolean; readonly verbose: boolean },\n operation: () => Value | PromiseLike<Value>,\n) {\n return Effect.tryPromise({\n try: () => Promise.resolve(operation()),\n catch: (cause) => new CliOperationFailed({ cause }),\n }).pipe(Effect.catch((failure) => commandFailure(phase, options, failure.cause)))\n}\n\nfunction commandFailure(phase: string, options: { readonly json: boolean; readonly verbose: boolean }, cause: unknown) {\n return Effect.gen(function* () {\n const diagnostic = diagnosticFromCause(phase, cause)\n\n if (!options.json) return yield* cliError(renderDiagnostic(diagnostic, options.verbose))\n\n const { details: _details, ...output } = diagnostic\n\n // oxlint-disable-next-line effecttsgo/prefer-schema-over-json -- CLI JSON is an intentionally stable plain object.\n yield* Console.log(JSON.stringify(output))\n\n return yield* new JsonCommandFailed({})\n })\n}\n\nroot.pipe(\n Command.withSubcommands([configuration, content, dev]),\n Command.run({ version: packageManifest.version }),\n Effect.provide(\n Layer.mergeAll(\n NodeFileSystem.layer,\n NodePath.layer,\n NodeCrypto.layer,\n NodeTerminal.layer,\n NodeStdio.layer,\n NodeChildProcessSpawner.layer.pipe(Layer.provide(Layer.merge(NodeFileSystem.layer, NodePath.layer))),\n FetchHttpClient.layer,\n ),\n ),\n NodeRuntime.runMain,\n)\n"],"mappings":";;;;;;;;;;;;;;ACwBA,MAAM,gBAAgB,KAAK,OAAO,MAAM,CAAC,CAAC,KAAK,KAAK,YAAY,GAAG,CAAC;AAEpE,MAAM,UAAU,KAAK,OAAO,UAAU,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;AAEjE,MAAM,UAAU,KAAK,QAAQ,SAAS,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAEpE,MAAM,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAE9D,MAAM,OAAO,QAAQ,KAAK,KAAK,CAAC,CAAC,KAC/B,QAAQ,gBAAgB;CACtB,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;CACjD,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;CACrD;CACA;CACA;CACA;AACF,CAAC,CACH;AAEA,MAAM,YAAY,SAAS,OAAO,WAAW;AAE7C,MAAM,YAAY,KAAK,QAAQ,WAAW,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAExE,MAAM,UAAU,KAAK,QAAQ,SAAS,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAEpE,MAAM,gBAAgB,QAAQ,KAAK,UAAU,EAAE,UAAU,IAAI,EAAE,gBAC7D,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,KAAK,UAAU,OAAO;CAE9B,OAAO,OAAO,cAAc;EAAE;EAAK;CAAM,GAAG,SAAS;AACvD,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,kDAAkD,CAAC;AAElF,MAAM,cAAc,QAAQ,KAAK,QAAQ,EAAE,UAAU,IAAI,EAAE,gBACzD,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,KAAK,UAAU,OAAO;CAE9B,OAAO,OAAO,YAAY;EAAE;EAAK;CAAM,GAAG,SAAS;AACrD,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,qDAAqD,CAAC;AAErF,MAAM,cAAc,QAAQ,KAAK,QAAQ;CAAE;CAAW;CAAW;AAAQ,IAAI,EAAE,WAAW,WAAW,cACnG,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,KAAK,UAAU,OAAO;CAE9B,OAAO,OAAO,YAAY;EAAE;EAAK;CAAM,GAAG,WAAW;EAAE;EAAW;CAAQ,CAAC;AAC7E,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,oDAAoD,CAAC;AAEpF,MAAM,eAAe,QAAQ,KAAK,SAAS;CAAE;CAAW;CAAW;AAAQ,IAAI,EAAE,WAAW,WAAW,cACrG,OAAO,IAAI,aAAa;CACtB,MAAM,EAAE,KAAK,UAAU,OAAO;CAE9B,OAAO,OAAO,aAAa;EAAE;EAAK;CAAM,GAAG,WAAW;EAAE;EAAW;CAAQ,CAAC;AAC9E,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,2CAA2C,CAAC;AAE3E,MAAM,UAAU,QAAQ,KAAK,SAAS,CAAC,CAAC,KACtC,QAAQ,gBAAgB;CAAC;CAAe;CAAa;CAAa;AAAY,CAAC,CACjF;AAEA,MAAM,4BAA4B,QAAQ,KAAK,SAAS,CAAC,SACvD,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO;CAEvB,MAAM,SAAS,OAAO,QAAQ,uBAAuB,eACnD,sBAAsB,QAAQ,eAAe,QAAQ,WAAW,QAAW,QAAQ,OAAO,CAC5F;CAEA,IAAI,QAAQ,MAEV,OAAO,QAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;MACpC,OAAO,QAAQ,IAAI,0BAA0B,MAAM,CAAC;CAE3D,IAAI,CAAC,OAAO,YACV,OAAO,OAAO,QAAQ,OAClB,IAAI,kBAAkB,CAAC,CAAC,IACxB,SAAS,sEAAsE;AACvF,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,kFAAkF,CAAC;AAElH,MAAM,gBAAgB,QAAQ,KAAK,eAAe,CAAC,CAAC,KAAK,QAAQ,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;AAE7G,MAAM,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAE9D,MAAM,mBAAmB,KAAK,OAAO,SAAS,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;AAEzE,MAAM,oBAAoB,KAAK,OAAO,MAAM,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;AAEvE,MAAM,WAAW,KAAK,QAAQ,UAAU,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAEtE,MAAM,QAAQ,KAAK,QAAQ,OAAO,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAEhE,MAAM,YAAY,KAAK,QAAQ,WAAW,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAExE,MAAM,MAAM,KAAK,QAAQ,KAAK,CAAC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC;AAE5D,MAAM,gBAAgB,QAAQ,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,WACxD,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO;CAEvB,MAAM,SAAS,OAAO,QAAQ,wBAAwB,eACpD,qBAAqB,QAAQ,eAAe,MAAM,QAAQ,WAAW,MAAS,CAChF;CAEA,IAAI,QAAQ,MAEV,OAAO,QAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;MAEzC,KAAK,MAAM,SAAS,OAAO,QAAQ;EACjC,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM,CAAC,CAAC,KACrC,MAAM,KAAK,cAAc,GAAG,GAC5B,MAAM,KAAK,cAAc,GAAG,GAC5B,MAAM,KAAK,sBAAsB,GAAG,GACpC,MAAM,UACR;EAEA,OAAO,QAAQ,IAAI,GAAG,KAAK,GAAG,MAAM,QAAQ,MAAM,SAAS,SAAS,MAAM,WAAW,IAAI;CAC3F;CAEF,IAAI,CAAC,OAAO,IACV,OAAO,OAAO,QAAQ,OAAO,IAAI,kBAAkB,CAAC,CAAC,IAAI,SAAS,4CAA4C;AAClH,CAAC,CACH,CAAC,CAAC,KAAK,QAAQ,gBAAgB,kDAAkD,CAAC;AAElF,MAAM,mBAAmB,QAAQ,KAC/B,aACA;CAAE;CAAkB;CAAmB;AAAQ,IAC9C,EAAE,kBAAkB,mBAAmB,cACtC,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO;CACvB,OAAO,QAAQ,yBAAyB,eACtC,0BAA0B,QAAQ,eAAe,QAAQ,WAAW,MAAS,CAC/E;CAEA,MAAM,gBAAgB,OAAO,qBAC3B,mBACA,kBACA,SACA,SACA,uBACF;CAEA,MAAM,SAAS,OAAO,QAAQ,0BAA0B,eACtD,wBAAwB;EACtB,SAAS,QAAQ;EACjB,SAAS,QAAQ,WAAW;EAC5B,SAAS,QAAQ;EACjB,GAAG;CACL,CAAC,CACH;CAEA,IAAI,QAAQ,MAEV,OAAO,QAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;MAEzC,OAAO,QAAQ,IACb,qCAAqC,OAAO,gBAAgB,OAAO,iBAAiB,sBAAsB,GAAG,EAC/G;AACJ,CAAC,CACL,CAAC,CAAC,KAAK,QAAQ,gBAAgB,mDAAmD,CAAC;AAEnF,MAAM,eAAe,QAAQ,KAC3B,SACA;CAAE;CAAW;CAAkB;CAAU;CAAO;CAAS;AAAI,IAC5D,EAAE,WAAW,kBAAkB,UAAU,OAAO,SAAS,UACxD,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO;CAEvB,IAAI,CAAC,YAAY,CAAC,OAChB,OAAO,OAAO,eAAe,mBAAmB,yBAAS,IAAI,MAAM,sCAAsC,CAAC;CAE5G,IAAI,aAAa,KACf,OAAO,QAAQ,qBAAqB,eAClC,0BAA0B,QAAQ,eAAe,QAAQ,WAAW,MAAS,CAC/E;CAEF,MAAM,gBACJ,aAAa,MACT,OAAO,qBAAqB,IAAI,kBAAkB,SAAS,SAAS,mBAAmB,IACvF;CAEN,MAAM,SAAS,OAAO,QAAQ,sBAAsB,eAClD,oBAAoB;EAClB,SAAS,QAAQ;EACjB,SAAS,QAAQ,WAAW;EAC5B;EACA;EACA;EACA,SAAS,QAAQ;EACjB,WAAW;CACb,CAAC,CACH;CAEA,IAAI,QAAQ,MAEV,OAAO,OAAO,QAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;CAGlD,KAAK,MAAM,UAAU,OAAO,SAC1B,OAAO,QAAQ,IAAI,GAAG,OAAO,WAAW,YAAY,cAAc,GAAG,QAAQ;CAE/E,IAAI,CAAC,OAAO,UAAU,OAAO,QAAQ,IAAI,yDAAyD;AACpG,CAAC,CACL,CAAC,CAAC,KAAK,QAAQ,gBAAgB,mDAAmD,CAAC;AAEnF,MAAM,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,KAAK,QAAQ,gBAAgB;CAAC;CAAe;CAAkB;AAAY,CAAC,CAAC;AAE7G,MAAM,uBAAuB,OAAO,GAAG,iCAAiC,CAAC,CAAC,WACxE,MACA,SACA,gBACA,SACA,OACA;CACA,MAAM,QAAQ,OAAO,OAAO,OAAO,WAAW,CAAC,CAAC,KAAK,OAAO,YAAY,EAAE,CAAC;CAC3E,MAAM,qBAAqB,OAAO,OAAO,SAAS,cAAc,CAAC,CAAC,KAAK,OAAO,MAAM;CAEpF,IAAI,CAAC,OAAO,OAAO,OAAO,eAAe,OAAO,yBAAS,IAAI,MAAM,wBAAwB,CAAC;CAE5F,IAAI,OAAO,OAAO,kBAAkB,KAAK,QAAQ,MAC/C,OAAO,OAAO,eAAe,OAAO,yBAAS,IAAI,MAAM,2BAA2B,CAAC;CAErF,MAAM,WAAW,OAAO,OAAO,kBAAkB,IAC7C,SAAS,MAAM,mBAAmB,KAAK,IACvC,SAAS,MAAM,OAAO,OAAO,SAAS,EAAE,SAAS,gBAAgB,QAAQ,CAAC,CAAC;CAE/E,IAAI,CAAC,UAAU,OAAO,OAAO,eAAe,OAAO,yBAAS,IAAI,MAAM,2BAA2B,CAAC;CAElG,OAAO;EACL,SAAS,WAAW;EACpB;EACA,MAAM,SAAS,OAAO,OAAO,OAAO,UAAU,CAAC,CAAC,KAAK,OAAO,YAAY,eAAe,CAAC;EACxF;EACA,SAAS;CACX;AACF,CAAC;AAED,SAAS,SAAS,SAAiB;CACjC,OAAO,IAAI,SAAS,UAAU;EAAE,OAAO,IAAI,MAAM,OAAO;EAAG,aAAa;CAAQ,CAAC;AACnF;AAEA,IAAM,qBAAN,cAAiC,OAAO,YAAgC,CAAC,CAAC,sBAAsB,EAC9F,OAAO,OAAO,OAAO,EACvB,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAM,oBAAN,cAAgC,OAAO,YAA+B,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;CAC/F,CAAmB,QAAQ,iBAAiB;CAC5C,CAAU,QAAQ,iBAAiB;AACrC;AAEA,SAAS,QACP,OACA,SACA,WACA;CACA,OAAO,OAAO,WAAW;EACvB,WAAW,QAAQ,QAAQ,UAAU,CAAC;EACtC,QAAQ,UAAU,IAAI,mBAAmB,EAAE,MAAM,CAAC;CACpD,CAAC,CAAC,CAAC,KAAK,OAAO,OAAO,YAAY,eAAe,OAAO,SAAS,QAAQ,KAAK,CAAC,CAAC;AAClF;AAEA,SAAS,eAAe,OAAe,SAAgE,OAAgB;CACrH,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,aAAa,oBAAoB,OAAO,KAAK;EAEnD,IAAI,CAAC,QAAQ,MAAM,OAAO,OAAO,SAAS,iBAAiB,YAAY,QAAQ,OAAO,CAAC;EAEvF,MAAM,EAAE,SAAS,UAAU,GAAG,WAAW;EAGzC,OAAO,QAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;EAEzC,OAAO,OAAO,IAAI,kBAAkB,CAAC,CAAC;CACxC,CAAC;AACH;AAEA,KAAK,KACH,QAAQ,gBAAgB;CAAC;CAAe;CAAS;AAAG,CAAC,GACrD,QAAQ,IAAI,EAAWA,QAAwB,CAAC,GAChD,OAAO,QACL,MAAM,SACJ,eAAe,OACf,SAAS,OACT,WAAW,OACX,aAAa,OACb,UAAU,OACV,wBAAwB,MAAM,KAAK,MAAM,QAAQ,MAAM,MAAM,eAAe,OAAO,SAAS,KAAK,CAAC,CAAC,GACnG,gBAAgB,KAClB,CACF,GACA,YAAY,OACd"}
@@ -1,4 +1,4 @@
1
- import { n as DocumentPreviewMessage, o as isDocumentPreviewMessage, t as DOCUMENT_PREVIEW_CHANNEL } from "./models-C9kF9JlQ.js";
1
+ import { n as DocumentPreviewMessage, o as isDocumentPreviewMessage, t as DOCUMENT_PREVIEW_CHANNEL } from "./models-5j67LMqW.js";
2
2
  import { Effect, Exit, Result, Schedule, Schema, Scope } from "effect";
3
3
 
4
4
  //#region ../protocol/src/internal/preview/bridge.ts
@@ -89,4 +89,4 @@ async function openSitePreviewConnection(options) {
89
89
 
90
90
  //#endregion
91
91
  export { openSitePreviewConnection as t };
92
- //# sourceMappingURL=connection-D5S9Iph-.js.map
92
+ //# sourceMappingURL=connection-BP80q4d-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-D5S9Iph-.js","names":["DocumentPreviewMessageSchema"],"sources":["../../../../protocol/src/internal/preview/bridge.ts","../../../src/runtime/preview/connection.ts"],"sourcesContent":["import type {\n DocumentPreviewMessage,\n PreviewOrigin,\n PreviewSessionId,\n PreviewSitePayload,\n StudioPreviewPayload,\n} from './models'\nimport type { Scope } from 'effect'\nimport { Effect, Result, Schedule, Schema } from 'effect'\nimport {\n DOCUMENT_PREVIEW_CHANNEL,\n DocumentPreviewMessage as DocumentPreviewMessageSchema,\n isDocumentPreviewMessage,\n} from './models'\n\nexport interface PreviewMessageEvent {\n readonly data: unknown\n readonly origin: string\n readonly source: object | null\n}\n\nexport interface PreviewMessageSource {\n readonly addEventListener: (type: 'message', listener: (event: PreviewMessageEvent) => void) => void\n readonly removeEventListener: (type: 'message', listener: (event: PreviewMessageEvent) => void) => void\n}\n\nexport interface PreviewMessageTarget {\n readonly postMessage: (message: DocumentPreviewMessage, targetOrigin: string) => void\n}\n\nexport type PreviewBridgeState = 'closed' | 'connecting' | 'ready'\n\nexport interface PreviewHostBridge {\n readonly reconnect: () => void\n readonly send: (payload: Exclude<StudioPreviewPayload, { readonly type: 'studio:connect' }>) => boolean\n readonly state: () => PreviewBridgeState\n readonly subscribe: (listener: (message: PreviewSitePayload) => void) => () => void\n}\n\nexport interface PreviewSiteBridge {\n readonly send: (payload: Exclude<PreviewSitePayload, { readonly type: 'preview:ready' }>) => boolean\n readonly subscribe: (listener: (message: StudioPreviewPayload) => void) => () => void\n}\n\nexport interface PreviewHostBridgeOptions {\n readonly handshakeIntervalMs?: number\n readonly sessionId: PreviewSessionId\n readonly target: () => PreviewMessageTarget | undefined\n readonly targetOrigin: PreviewOrigin\n readonly view: PreviewMessageSource\n}\n\nexport interface PreviewSiteBridgeOptions {\n readonly parent: PreviewMessageTarget\n readonly parentOrigin: PreviewOrigin\n readonly route: PreviewSitePayload & { readonly type: 'preview:ready' }\n readonly sessionId: PreviewSessionId\n readonly view: PreviewMessageSource\n}\n\nexport function makePreviewHostBridge(\n options: PreviewHostBridgeOptions,\n): Effect.Effect<PreviewHostBridge, never, Scope.Scope> {\n return Effect.acquireRelease(\n Effect.context<never>().pipe(\n Effect.map((context) => createPreviewHostBridge(options, Effect.runForkWith(context))),\n ),\n (bridge) => Effect.sync(() => bridge.close()),\n ).pipe(Effect.map(({ close: _close, ...bridge }) => bridge))\n}\n\nexport function makePreviewSiteBridge(\n options: PreviewSiteBridgeOptions,\n): Effect.Effect<PreviewSiteBridge, never, Scope.Scope> {\n return Effect.acquireRelease(\n Effect.sync(() => createPreviewSiteBridge(options)),\n (bridge) => Effect.sync(() => bridge.close()),\n ).pipe(Effect.map(({ close: _close, ...bridge }) => bridge))\n}\n\nfunction createPreviewHostBridge(options: PreviewHostBridgeOptions, runFork: typeof Effect.runFork) {\n const listeners = new Set<(message: PreviewSitePayload) => void>()\n let retry: ReturnType<typeof Effect.runFork> | undefined\n let state: PreviewBridgeState = 'connecting'\n\n const stopRetry = (): void => {\n if (retry === undefined) return\n retry.interruptUnsafe()\n retry = undefined\n }\n\n const post = (payload: StudioPreviewPayload): boolean => {\n const target = options.target()\n\n if (!target) return false\n target.postMessage(envelope(options.sessionId, payload), options.targetOrigin)\n\n return true\n }\n\n const connect = (): void => {\n post({ type: 'studio:connect' })\n }\n\n const reconnect = (): void => {\n if (state === 'closed') return\n state = 'connecting'\n stopRetry()\n const interval = options.handshakeIntervalMs ?? 250\n retry = runFork(Effect.sync(connect).pipe(Effect.repeat(Schedule.spaced(interval)), Effect.delay(interval)))\n connect()\n }\n\n const receive = (event: PreviewMessageEvent): void => {\n const target = options.target()\n\n if (!target) return\n const message = receivePreviewMessage(event, target, options.targetOrigin, options.sessionId)\n\n if (!message || !isPreviewSiteMessage(message)) return\n\n if (message.type === 'preview:ready') {\n state = 'ready'\n stopRetry()\n }\n\n for (const listener of listeners) listener(message)\n }\n\n const close = (): void => {\n if (state === 'closed') return\n state = 'closed'\n stopRetry()\n options.view.removeEventListener('message', receive)\n listeners.clear()\n }\n\n options.view.addEventListener('message', receive)\n reconnect()\n\n return {\n close,\n reconnect,\n send: (payload: Exclude<StudioPreviewPayload, { readonly type: 'studio:connect' }>) =>\n state === 'ready' && post(payload),\n state: () => state,\n subscribe: (listener: (message: PreviewSitePayload) => void) => {\n listeners.add(listener)\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction createPreviewSiteBridge(options: PreviewSiteBridgeOptions) {\n const listeners = new Set<(message: StudioPreviewPayload) => void>()\n let active = false\n let closed = false\n\n const post = (payload: PreviewSitePayload): boolean => {\n if (!active || closed) return false\n options.parent.postMessage(envelope(options.sessionId, payload), options.parentOrigin)\n\n return true\n }\n\n const receive = (event: PreviewMessageEvent): void => {\n if (closed) return\n const message = receivePreviewMessage(event, options.parent, options.parentOrigin, options.sessionId)\n\n if (!message || !isStudioPreviewMessage(message)) return\n\n if (message.type === 'studio:connect') {\n active = true\n post(options.route)\n }\n\n for (const listener of listeners) listener(message)\n }\n\n const close = (): void => {\n if (closed) return\n closed = true\n active = false\n options.view.removeEventListener('message', receive)\n listeners.clear()\n }\n\n options.view.addEventListener('message', receive)\n\n return {\n close,\n send: post,\n subscribe: (listener: (message: StudioPreviewPayload) => void) => {\n listeners.add(listener)\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction envelope(\n sessionId: PreviewSessionId,\n payload: PreviewSitePayload | StudioPreviewPayload,\n): DocumentPreviewMessage {\n return Result.getOrThrow(\n Schema.decodeResult(Schema.toType(DocumentPreviewMessageSchema))({\n channel: DOCUMENT_PREVIEW_CHANNEL,\n sessionId,\n ...payload,\n }),\n )\n}\n\nfunction receivePreviewMessage(\n event: PreviewMessageEvent,\n source: PreviewMessageTarget,\n origin: PreviewOrigin,\n sessionId: PreviewSessionId,\n): DocumentPreviewMessage | undefined {\n if (event.origin !== origin || event.source !== source || !isDocumentPreviewMessage(event.data)) return undefined\n\n return event.data.sessionId === sessionId ? event.data : undefined\n}\n\nfunction isPreviewSiteMessage(\n message: DocumentPreviewMessage,\n): message is Extract<DocumentPreviewMessage, { readonly type: `preview:${string}` }> {\n return message.type.startsWith('preview:')\n}\n\nfunction isStudioPreviewMessage(\n message: DocumentPreviewMessage,\n): message is Extract<DocumentPreviewMessage, { readonly type: `studio:${string}` }> {\n return message.type.startsWith('studio:')\n}\n","import type { PublicPath } from '@internal/protocol/Documents'\nimport type { PreviewOrigin, PreviewSessionId, PreviewSiteBridge } from '@internal/protocol/Preview'\nimport { makePreviewSiteBridge } from '@internal/protocol/Preview'\nimport { Effect, Exit, Scope } from 'effect'\n\nexport interface SitePreviewConnection extends PreviewSiteBridge {\n readonly close: () => Promise<void>\n}\n\n// oxlint-disable-next-line effecttsgo/async-function -- This browser adapter exposes the Effect-managed preview bridge through a Promise API consumed by Nuxt.\nexport async function openSitePreviewConnection(options: {\n readonly editorOrigin: PreviewOrigin\n readonly route: PublicPath\n readonly sessionId: PreviewSessionId\n}): Promise<SitePreviewConnection> {\n const scope = await Effect.runPromise(Scope.make())\n\n try {\n const bridge = await Effect.runPromise(\n makePreviewSiteBridge({\n parent: window.parent,\n parentOrigin: options.editorOrigin,\n route: { path: options.route, type: 'preview:ready' },\n sessionId: options.sessionId,\n view: window,\n }).pipe(Effect.provideService(Scope.Scope, scope)),\n )\n\n let closed = false\n\n return {\n // oxlint-disable-next-line effecttsgo/async-function -- Closing adapts Effect scope finalization to the connection's Promise contract.\n async close() {\n if (closed) return\n closed = true\n await Effect.runPromise(Scope.close(scope, Exit.void))\n },\n send: bridge.send,\n subscribe: bridge.subscribe,\n }\n } catch (cause) {\n await Effect.runPromise(Scope.close(scope, Exit.fail(cause)))\n throw cause\n }\n}\n"],"mappings":";;;;AAuEA,SAAgB,sBACd,SACsD;CACtD,OAAO,OAAO,eACZ,OAAO,WAAW,wBAAwB,OAAO,CAAC,IACjD,WAAW,OAAO,WAAW,OAAO,MAAM,CAAC,CAC9C,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE,OAAO,QAAQ,GAAG,aAAa,MAAM,CAAC;AAC7D;AA4EA,SAAS,wBAAwB,SAAmC;CAClE,MAAM,4BAAY,IAAI,IAA6C;CACnE,IAAI,SAAS;CACb,IAAI,SAAS;CAEb,MAAM,QAAQ,YAAyC;EACrD,IAAI,CAAC,UAAU,QAAQ,OAAO;EAC9B,QAAQ,OAAO,YAAY,SAAS,QAAQ,WAAW,OAAO,GAAG,QAAQ,YAAY;EAErF,OAAO;CACT;CAEA,MAAM,WAAW,UAAqC;EACpD,IAAI,QAAQ;EACZ,MAAM,UAAU,sBAAsB,OAAO,QAAQ,QAAQ,QAAQ,cAAc,QAAQ,SAAS;EAEpG,IAAI,CAAC,WAAW,CAAC,uBAAuB,OAAO,GAAG;EAElD,IAAI,QAAQ,SAAS,kBAAkB;GACrC,SAAS;GACT,KAAK,QAAQ,KAAK;EACpB;EAEA,KAAK,MAAM,YAAY,WAAW,SAAS,OAAO;CACpD;CAEA,MAAM,cAAoB;EACxB,IAAI,QAAQ;EACZ,SAAS;EACT,SAAS;EACT,QAAQ,KAAK,oBAAoB,WAAW,OAAO;EACnD,UAAU,MAAM;CAClB;CAEA,QAAQ,KAAK,iBAAiB,WAAW,OAAO;CAEhD,OAAO;EACL;EACA,MAAM;EACN,YAAY,aAAsD;GAChE,UAAU,IAAI,QAAQ;GAEtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;AAEA,SAAS,SACP,WACA,SACwB;CACxB,OAAO,OAAO,WACZ,OAAO,aAAa,OAAO,OAAOA,sBAA4B,CAAC,CAAC,CAAC;EAC/D,SAAS;EACT;EACA,GAAG;CACL,CAAC,CACH;AACF;AAEA,SAAS,sBACP,OACA,QACA,QACA,WACoC;CACpC,IAAI,MAAM,WAAW,UAAU,MAAM,WAAW,UAAU,CAAC,yBAAyB,MAAM,IAAI,GAAG,OAAO;CAExG,OAAO,MAAM,KAAK,cAAc,YAAY,MAAM,OAAO;AAC3D;AAQA,SAAS,uBACP,SACmF;CACnF,OAAO,QAAQ,KAAK,WAAW,SAAS;AAC1C;;;;ACjOA,eAAsB,0BAA0B,SAIb;CACjC,MAAM,QAAQ,MAAM,OAAO,WAAW,MAAM,KAAK,CAAC;CAElD,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,WAC1B,sBAAsB;GACpB,QAAQ,OAAO;GACf,cAAc,QAAQ;GACtB,OAAO;IAAE,MAAM,QAAQ;IAAO,MAAM;GAAgB;GACpD,WAAW,QAAQ;GACnB,MAAM;EACR,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,MAAM,OAAO,KAAK,CAAC,CACnD;EAEA,IAAI,SAAS;EAEb,OAAO;GAEL,MAAM,QAAQ;IACZ,IAAI,QAAQ;IACZ,SAAS;IACT,MAAM,OAAO,WAAW,MAAM,MAAM,OAAO,KAAK,IAAI,CAAC;GACvD;GACA,MAAM,OAAO;GACb,WAAW,OAAO;EACpB;CACF,SAAS,OAAO;EACd,MAAM,OAAO,WAAW,MAAM,MAAM,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC;EAC5D,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"connection-BP80q4d-.js","names":["DocumentPreviewMessageSchema"],"sources":["../../../../protocol/src/internal/preview/bridge.ts","../../../src/runtime/preview/connection.ts"],"sourcesContent":["import type {\n DocumentPreviewMessage,\n PreviewOrigin,\n PreviewSessionId,\n PreviewSitePayload,\n StudioPreviewPayload,\n} from './models'\nimport type { Scope } from 'effect'\nimport { Effect, Result, Schedule, Schema } from 'effect'\nimport {\n DOCUMENT_PREVIEW_CHANNEL,\n DocumentPreviewMessage as DocumentPreviewMessageSchema,\n isDocumentPreviewMessage,\n} from './models'\n\nexport interface PreviewMessageEvent {\n readonly data: unknown\n readonly origin: string\n readonly source: object | null\n}\n\nexport interface PreviewMessageSource {\n readonly addEventListener: (type: 'message', listener: (event: PreviewMessageEvent) => void) => void\n readonly removeEventListener: (type: 'message', listener: (event: PreviewMessageEvent) => void) => void\n}\n\nexport interface PreviewMessageTarget {\n readonly postMessage: (message: DocumentPreviewMessage, targetOrigin: string) => void\n}\n\nexport type PreviewBridgeState = 'closed' | 'connecting' | 'ready'\n\nexport interface PreviewHostBridge {\n readonly reconnect: () => void\n readonly send: (payload: Exclude<StudioPreviewPayload, { readonly type: 'studio:connect' }>) => boolean\n readonly state: () => PreviewBridgeState\n readonly subscribe: (listener: (message: PreviewSitePayload) => void) => () => void\n}\n\nexport interface PreviewSiteBridge {\n readonly send: (payload: Exclude<PreviewSitePayload, { readonly type: 'preview:ready' }>) => boolean\n readonly subscribe: (listener: (message: StudioPreviewPayload) => void) => () => void\n}\n\nexport interface PreviewHostBridgeOptions {\n readonly handshakeIntervalMs?: number\n readonly sessionId: PreviewSessionId\n readonly target: () => PreviewMessageTarget | undefined\n readonly targetOrigin: PreviewOrigin\n readonly view: PreviewMessageSource\n}\n\nexport interface PreviewSiteBridgeOptions {\n readonly parent: PreviewMessageTarget\n readonly parentOrigin: PreviewOrigin\n readonly route: PreviewSitePayload & { readonly type: 'preview:ready' }\n readonly sessionId: PreviewSessionId\n readonly view: PreviewMessageSource\n}\n\nexport function makePreviewHostBridge(\n options: PreviewHostBridgeOptions,\n): Effect.Effect<PreviewHostBridge, never, Scope.Scope> {\n return Effect.acquireRelease(\n Effect.context<never>().pipe(\n Effect.map((context) => createPreviewHostBridge(options, Effect.runForkWith(context))),\n ),\n (bridge) => Effect.sync(() => bridge.close()),\n ).pipe(Effect.map(({ close: _close, ...bridge }) => bridge))\n}\n\nexport function makePreviewSiteBridge(\n options: PreviewSiteBridgeOptions,\n): Effect.Effect<PreviewSiteBridge, never, Scope.Scope> {\n return Effect.acquireRelease(\n Effect.sync(() => createPreviewSiteBridge(options)),\n (bridge) => Effect.sync(() => bridge.close()),\n ).pipe(Effect.map(({ close: _close, ...bridge }) => bridge))\n}\n\nfunction createPreviewHostBridge(options: PreviewHostBridgeOptions, runFork: typeof Effect.runFork) {\n const listeners = new Set<(message: PreviewSitePayload) => void>()\n let retry: ReturnType<typeof Effect.runFork> | undefined\n let state: PreviewBridgeState = 'connecting'\n\n const stopRetry = (): void => {\n if (retry === undefined) return\n retry.interruptUnsafe()\n retry = undefined\n }\n\n const post = (payload: StudioPreviewPayload): boolean => {\n const target = options.target()\n\n if (!target) return false\n target.postMessage(envelope(options.sessionId, payload), options.targetOrigin)\n\n return true\n }\n\n const connect = (): void => {\n post({ type: 'studio:connect' })\n }\n\n const reconnect = (): void => {\n if (state === 'closed') return\n state = 'connecting'\n stopRetry()\n const interval = options.handshakeIntervalMs ?? 250\n retry = runFork(Effect.sync(connect).pipe(Effect.repeat(Schedule.spaced(interval)), Effect.delay(interval)))\n connect()\n }\n\n const receive = (event: PreviewMessageEvent): void => {\n const target = options.target()\n\n if (!target) return\n const message = receivePreviewMessage(event, target, options.targetOrigin, options.sessionId)\n\n if (!message || !isPreviewSiteMessage(message)) return\n\n if (message.type === 'preview:ready') {\n state = 'ready'\n stopRetry()\n }\n\n for (const listener of listeners) listener(message)\n }\n\n const close = (): void => {\n if (state === 'closed') return\n state = 'closed'\n stopRetry()\n options.view.removeEventListener('message', receive)\n listeners.clear()\n }\n\n options.view.addEventListener('message', receive)\n reconnect()\n\n return {\n close,\n reconnect,\n send: (payload: Exclude<StudioPreviewPayload, { readonly type: 'studio:connect' }>) =>\n state === 'ready' && post(payload),\n state: () => state,\n subscribe: (listener: (message: PreviewSitePayload) => void) => {\n listeners.add(listener)\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction createPreviewSiteBridge(options: PreviewSiteBridgeOptions) {\n const listeners = new Set<(message: StudioPreviewPayload) => void>()\n let active = false\n let closed = false\n\n const post = (payload: PreviewSitePayload): boolean => {\n if (!active || closed) return false\n options.parent.postMessage(envelope(options.sessionId, payload), options.parentOrigin)\n\n return true\n }\n\n const receive = (event: PreviewMessageEvent): void => {\n if (closed) return\n const message = receivePreviewMessage(event, options.parent, options.parentOrigin, options.sessionId)\n\n if (!message || !isStudioPreviewMessage(message)) return\n\n if (message.type === 'studio:connect') {\n active = true\n post(options.route)\n }\n\n for (const listener of listeners) listener(message)\n }\n\n const close = (): void => {\n if (closed) return\n closed = true\n active = false\n options.view.removeEventListener('message', receive)\n listeners.clear()\n }\n\n options.view.addEventListener('message', receive)\n\n return {\n close,\n send: post,\n subscribe: (listener: (message: StudioPreviewPayload) => void) => {\n listeners.add(listener)\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction envelope(\n sessionId: PreviewSessionId,\n payload: PreviewSitePayload | StudioPreviewPayload,\n): DocumentPreviewMessage {\n return Result.getOrThrow(\n Schema.decodeResult(Schema.toType(DocumentPreviewMessageSchema))({\n channel: DOCUMENT_PREVIEW_CHANNEL,\n sessionId,\n ...payload,\n }),\n )\n}\n\nfunction receivePreviewMessage(\n event: PreviewMessageEvent,\n source: PreviewMessageTarget,\n origin: PreviewOrigin,\n sessionId: PreviewSessionId,\n): DocumentPreviewMessage | undefined {\n if (event.origin !== origin || event.source !== source || !isDocumentPreviewMessage(event.data)) return undefined\n\n return event.data.sessionId === sessionId ? event.data : undefined\n}\n\nfunction isPreviewSiteMessage(\n message: DocumentPreviewMessage,\n): message is Extract<DocumentPreviewMessage, { readonly type: `preview:${string}` }> {\n return message.type.startsWith('preview:')\n}\n\nfunction isStudioPreviewMessage(\n message: DocumentPreviewMessage,\n): message is Extract<DocumentPreviewMessage, { readonly type: `studio:${string}` }> {\n return message.type.startsWith('studio:')\n}\n","import type { PublicPath } from '@internal/protocol/Documents'\nimport type { PreviewOrigin, PreviewSessionId, PreviewSiteBridge } from '@internal/protocol/Preview'\nimport { makePreviewSiteBridge } from '@internal/protocol/Preview'\nimport { Effect, Exit, Scope } from 'effect'\n\nexport interface SitePreviewConnection extends PreviewSiteBridge {\n readonly close: () => Promise<void>\n}\n\n// oxlint-disable-next-line effecttsgo/async-function -- This browser adapter exposes the Effect-managed preview bridge through a Promise API consumed by Nuxt.\nexport async function openSitePreviewConnection(options: {\n readonly editorOrigin: PreviewOrigin\n readonly route: PublicPath\n readonly sessionId: PreviewSessionId\n}): Promise<SitePreviewConnection> {\n const scope = await Effect.runPromise(Scope.make())\n\n try {\n const bridge = await Effect.runPromise(\n makePreviewSiteBridge({\n parent: window.parent,\n parentOrigin: options.editorOrigin,\n route: { path: options.route, type: 'preview:ready' },\n sessionId: options.sessionId,\n view: window,\n }).pipe(Effect.provideService(Scope.Scope, scope)),\n )\n\n let closed = false\n\n return {\n // oxlint-disable-next-line effecttsgo/async-function -- Closing adapts Effect scope finalization to the connection's Promise contract.\n async close() {\n if (closed) return\n closed = true\n await Effect.runPromise(Scope.close(scope, Exit.void))\n },\n send: bridge.send,\n subscribe: bridge.subscribe,\n }\n } catch (cause) {\n await Effect.runPromise(Scope.close(scope, Exit.fail(cause)))\n throw cause\n }\n}\n"],"mappings":";;;;AAuEA,SAAgB,sBACd,SACsD;CACtD,OAAO,OAAO,eACZ,OAAO,WAAW,wBAAwB,OAAO,CAAC,IACjD,WAAW,OAAO,WAAW,OAAO,MAAM,CAAC,CAC9C,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE,OAAO,QAAQ,GAAG,aAAa,MAAM,CAAC;AAC7D;AA4EA,SAAS,wBAAwB,SAAmC;CAClE,MAAM,4BAAY,IAAI,IAA6C;CACnE,IAAI,SAAS;CACb,IAAI,SAAS;CAEb,MAAM,QAAQ,YAAyC;EACrD,IAAI,CAAC,UAAU,QAAQ,OAAO;EAC9B,QAAQ,OAAO,YAAY,SAAS,QAAQ,WAAW,OAAO,GAAG,QAAQ,YAAY;EAErF,OAAO;CACT;CAEA,MAAM,WAAW,UAAqC;EACpD,IAAI,QAAQ;EACZ,MAAM,UAAU,sBAAsB,OAAO,QAAQ,QAAQ,QAAQ,cAAc,QAAQ,SAAS;EAEpG,IAAI,CAAC,WAAW,CAAC,uBAAuB,OAAO,GAAG;EAElD,IAAI,QAAQ,SAAS,kBAAkB;GACrC,SAAS;GACT,KAAK,QAAQ,KAAK;EACpB;EAEA,KAAK,MAAM,YAAY,WAAW,SAAS,OAAO;CACpD;CAEA,MAAM,cAAoB;EACxB,IAAI,QAAQ;EACZ,SAAS;EACT,SAAS;EACT,QAAQ,KAAK,oBAAoB,WAAW,OAAO;EACnD,UAAU,MAAM;CAClB;CAEA,QAAQ,KAAK,iBAAiB,WAAW,OAAO;CAEhD,OAAO;EACL;EACA,MAAM;EACN,YAAY,aAAsD;GAChE,UAAU,IAAI,QAAQ;GAEtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;AAEA,SAAS,SACP,WACA,SACwB;CACxB,OAAO,OAAO,WACZ,OAAO,aAAa,OAAO,OAAOA,sBAA4B,CAAC,CAAC,CAAC;EAC/D,SAAS;EACT;EACA,GAAG;CACL,CAAC,CACH;AACF;AAEA,SAAS,sBACP,OACA,QACA,QACA,WACoC;CACpC,IAAI,MAAM,WAAW,UAAU,MAAM,WAAW,UAAU,CAAC,yBAAyB,MAAM,IAAI,GAAG,OAAO;CAExG,OAAO,MAAM,KAAK,cAAc,YAAY,MAAM,OAAO;AAC3D;AAQA,SAAS,uBACP,SACmF;CACnF,OAAO,QAAQ,KAAK,WAAW,SAAS;AAC1C;;;;ACjOA,eAAsB,0BAA0B,SAIb;CACjC,MAAM,QAAQ,MAAM,OAAO,WAAW,MAAM,KAAK,CAAC;CAElD,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,WAC1B,sBAAsB;GACpB,QAAQ,OAAO;GACf,cAAc,QAAQ;GACtB,OAAO;IAAE,MAAM,QAAQ;IAAO,MAAM;GAAgB;GACpD,WAAW,QAAQ;GACnB,MAAM;EACR,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,MAAM,OAAO,KAAK,CAAC,CACnD;EAEA,IAAI,SAAS;EAEb,OAAO;GAEL,MAAM,QAAQ;IACZ,IAAI,QAAQ;IACZ,SAAS;IACT,MAAM,OAAO,WAAW,MAAM,MAAM,OAAO,KAAK,IAAI,CAAC;GACvD;GACA,MAAM,OAAO;GACb,WAAW,OAAO;EACpB;CACF,SAAS,OAAO;EACd,MAAM,OAAO,WAAW,MAAM,MAAM,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC;EAC5D,MAAM;CACR;AACF"}
@@ -1,10 +1,10 @@
1
1
  import { l as CMS_READINESS_PATH, p as STUDIO_COLLABORATION_PATH, u as STUDIO_API_PATH } from "./HttpPaths-c9nLZ9H2.js";
2
2
  import { createCmsContentClient, readCmsContentDirectory } from "./Content.js";
3
- import { t as AuthoringCatalog } from "./Configuration-BU-UyGoH.js";
3
+ import { t as AuthoringCatalog } from "./Configuration-JQ1qyaU0.js";
4
4
  import { loadCmsConfiguration } from "./internal/cms-config.js";
5
5
  import { cmsRuntimeConfigurationDefaults, cmsRuntimeConfigurationFromEnvironment, compileCmsConfiguration, resolveCmsInstallation } from "./internal/configuration.js";
6
- import { a as embeddedMigrations, i as createCmsBetterAuth, n as scopedDatabaseUrl, t as installCms } from "./installation-fZtNxtoW.js";
7
- import { Effect, Layer, References, Result, Schema } from "effect";
6
+ import { a as checkConfiguration, c as embeddedMigrations, i as createCmsBetterAuth, n as scopedDatabaseUrl, s as postgresConfigurationCheckLayer, t as installCms } from "./installation-BoG8E3nJ.js";
7
+ import { Effect, Layer, Redacted, References, Result, Schema } from "effect";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { readFile } from "node:fs/promises";
10
10
  import { resolve } from "node:path";
@@ -86,6 +86,26 @@ const reconcileLocalAdministrator = Effect.fn("LocalAdministrator.reconcile")(fu
86
86
 
87
87
  //#endregion
88
88
  //#region src/internal/dev-lifecycle.ts
89
+ async function checkCmsConfiguration(rootDir, envFile, verbose = false) {
90
+ const project = await inPhase("configuration.load", () => loadConfiguration(rootDir, envFile));
91
+ const authoring = await inPhase("configuration.authoring", () => prepareAuthoring(rootDir, verbose));
92
+ const resolved = inPhaseSync("configuration.compile", () => resolveCmsInstallation(project.authored.configuration, project.runtime, authoring));
93
+ const pool = new Pool({ connectionString: resolved.database.url });
94
+ try {
95
+ const pending = await inPhase("configuration.migrations", () => verifyMigrations(pool, resolved.database.schema));
96
+ if (pending > 0) throw new CmsLifecycleFailed({
97
+ cause: /* @__PURE__ */ new Error(`${pending} database migration${pending === 1 ? " is" : "s are"} pending.`),
98
+ message: "Run cms dev bootstrap before checking configuration changes.",
99
+ phase: "configuration.migrations"
100
+ });
101
+ } finally {
102
+ await pool.end();
103
+ }
104
+ return inPhase("configuration.check", () => Effect.runPromise(checkConfiguration(resolved.configuration, { documentModel: resolved.documentModel }).pipe(Effect.provide(postgresConfigurationCheckLayer({
105
+ schema: resolved.database.schema,
106
+ url: Redacted.make(resolved.database.url)
107
+ })))));
108
+ }
89
109
  const nodeLayer = Layer.merge(NodeCrypto.layer, Layer.merge(NodeFileSystem.layer, NodePath.layer));
90
110
  const InitializationStatus = Schema.Struct({ needsAdministrator: Schema.optionalKey(Schema.Boolean) });
91
111
  const CauseCarrier = Schema.Struct({ cause: Schema.Unknown });
@@ -258,7 +278,7 @@ async function bootstrapCmsDevelopment(options) {
258
278
  publish: options.publish
259
279
  }));
260
280
  if (!plan.valid) {
261
- const details = [...plan.conflicts.map((entry) => `${entry.sourcePath}: conflicts with the current CMS content`), ...plan.issues.map((issue) => `${issue.sourcePath ?? issue.key ?? "content"}${issue.field ? ` (${issue.field})` : ""}: ${issue.message}`)];
281
+ const details = [...plan.conflicts.map((entry) => `${entry.filePath}: conflicts with the current CMS content`), ...plan.issues.map((issue) => `${issue.documentId ?? issue.key ?? "content"}${issue.field ? ` (${issue.field})` : ""}: ${issue.message}`)];
262
282
  throw new CmsLifecycleFailed({
263
283
  cause: /* @__PURE__ */ new Error(`Bootstrap content has conflicts or validation errors. ${details.join(" ")}`),
264
284
  message: `Bootstrap content has conflicts or validation errors. ${details.join(" ")}`,
@@ -511,5 +531,5 @@ function inPhaseSync(phase, operation) {
511
531
  }
512
532
 
513
533
  //#endregion
514
- export { resetCmsDevelopment as i, doctorCmsDevelopment as n, loadCmsProjectEnvironment as r, bootstrapCmsDevelopment as t };
515
- //# sourceMappingURL=dev-lifecycle-D3f9-upa.js.map
534
+ export { resetCmsDevelopment as a, loadCmsProjectEnvironment as i, checkCmsConfiguration as n, doctorCmsDevelopment as r, bootstrapCmsDevelopment as t };
535
+ //# sourceMappingURL=dev-lifecycle-DdBluSiR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-lifecycle-DdBluSiR.js","names":["AuthoringCatalogSchema"],"sources":["../../../../sql-pg/src/Migration.ts","../../../../auth/src/LocalDevelopment.ts","../../../src/internal/dev-lifecycle.ts"],"sourcesContent":["import type { PgPoolConfig } from '@effect/sql-pg/PgClient'\nimport { Effect, Schema } from 'effect'\nimport { embeddedMigrations } from './internal/database/embedded-migrations.generated'\nimport { migrateCmsDatabase } from './internal/database/migrations'\nimport { schemaClientLayer } from './internal/postgres/scoped-client'\n\nexport interface PostgresMigration {\n readonly createdAt: number\n readonly hash: string\n readonly name: string\n readonly statements: ReadonlyArray<string>\n}\n\n/** Migration history used by development tooling to verify pending SQL without mutating the database. */\nexport const postgresMigrations: ReadonlyArray<PostgresMigration> = Object.freeze(\n embeddedMigrations.map((migration) =>\n Object.freeze({\n createdAt: migration.folderMillis,\n hash: migration.hash,\n name: migration.name,\n statements: Object.freeze([...migration.sql]),\n }),\n ),\n)\n\nexport class MigrationFailed extends Schema.TaggedError<MigrationFailed>()('Postgres.MigrationFailed', {\n cause: Schema.Defect(),\n operation: Schema.String,\n}) {}\n\nexport interface PostgresMigrationOptions extends PgPoolConfig {\n readonly schema: string\n}\n\nexport function migratePostgres(options: PostgresMigrationOptions): Effect.Effect<void, MigrationFailed> {\n const { schema, ...poolOptions } = options\n\n return migrateCmsDatabase(schema).pipe(\n Effect.provide(\n schemaClientLayer({ ...poolOptions, applicationName: options.applicationName ?? '@internal/migrate' }, schema),\n ),\n Effect.mapError((cause) => new MigrationFailed({ cause, operation: 'Postgres.migrate' })),\n )\n}\n","import type { BetterAuthOptions } from 'better-auth'\nimport { Effect, Schema } from 'effect'\nimport { createCmsBetterAuth } from './internal/better-auth'\n\nexport interface LocalAdministratorOptions {\n readonly baseUrl: string\n readonly database: NonNullable<BetterAuthOptions['database']>\n readonly email: string\n readonly name: string\n readonly password: string\n readonly secret: string\n}\n\nexport type LocalAdministratorResult = 'created' | 'updated' | 'verified'\n\nexport class LocalAdministratorFailed extends Schema.TaggedError<LocalAdministratorFailed>()(\n 'LocalAdministrator.Failed',\n { cause: Schema.Defect() },\n) {}\n\n/** Reconciles the one local-development administrator without exposing Better Auth's admin routes. */\nexport const reconcileLocalAdministrator = Effect.fn('LocalAdministrator.reconcile')(function* (\n options: LocalAdministratorOptions,\n) {\n const auth = createCmsBetterAuth({\n baseURL: options.baseUrl,\n database: options.database,\n secret: options.secret,\n })\n\n return yield* Effect.tryPromise({\n // oxlint-disable-next-line effecttsgo/async-function -- Better Auth's internal adapter exposes its transaction as one Promise workflow.\n try: async () => {\n const context = await auth.$context\n const existing = await context.internalAdapter.findUserByEmail(options.email, { includeAccounts: true })\n\n if (!existing) {\n const user = await context.internalAdapter.createUser(\n { email: options.email, name: options.name, role: 'administrator' },\n { method: 'admin' },\n )\n\n const password = await context.password.hash(options.password)\n await context.internalAdapter.linkAccount({\n accountId: user.id,\n password,\n providerId: 'credential',\n userId: user.id,\n })\n\n return 'created' as const\n }\n\n const isAdministrator =\n Schema.is(Schema.Struct({ role: Schema.String }))(existing.user) && existing.user.role === 'administrator'\n\n let changed = existing.user.name !== options.name || !isAdministrator\n\n if (changed)\n await context.internalAdapter.updateUser(existing.user.id, {\n name: options.name,\n role: 'administrator',\n })\n\n const credential = existing.accounts.find(\n (account) => account.providerId === 'credential' && account.accountId === existing.user.id,\n )\n\n const passwordMatches = credential?.password\n ? await context.password.verify({ hash: credential.password, password: options.password })\n : false\n\n if (!passwordMatches) {\n const password = await context.password.hash(options.password)\n\n if (credential) await context.internalAdapter.updatePassword(existing.user.id, password)\n else\n await context.internalAdapter.createAccount({\n accountId: existing.user.id,\n password,\n providerId: 'credential',\n userId: existing.user.id,\n })\n\n changed = true\n }\n\n return changed ? ('updated' as const) : ('verified' as const)\n },\n catch: (cause) => new LocalAdministratorFailed({ cause }),\n })\n})\n","/* oxlint-disable effecttsgo/async-function effecttsgo/global-fetch effecttsgo/global-timers effecttsgo/new-promise effecttsgo/node-builtin-import -- The CLI boundary coordinates Promise-based Nuxt, pg, S3, fetch, WebSocket, and filesystem APIs. */\nimport type { AuthoringCatalog } from '@internal/protocol/Configuration'\nimport type { ConfigurationCheckReport } from '@internal/protocol/ConfigurationChanges'\nimport { AuthoringCatalog as AuthoringCatalogSchema } from '@internal/protocol/Configuration'\nimport { CMS_READINESS_PATH, STUDIO_API_PATH, STUDIO_COLLABORATION_PATH } from '@internal/protocol/HttpPaths'\nimport { NodeCrypto, NodeFileSystem, NodePath } from '@effect/platform-node-shared'\nimport {\n DeleteObjectCommand,\n HeadBucketCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3'\nimport { loadNuxt, loadNuxtConfig } from '@nuxt/kit'\nimport { setupDotenv } from 'c12'\nimport { Effect, Layer, Redacted, References, Result, Schema } from 'effect'\nimport { Pool } from 'pg'\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { randomUUID } from 'node:crypto'\nimport { resolve } from 'node:path'\nimport { createCmsContentClient, readCmsContentDirectory } from '../Content'\nimport { postgresMigrations } from '@internal/sql-pg/Migration'\nimport { postgresConfigurationCheckLayer } from '@internal/sql-pg/Postgres'\nimport { checkConfiguration } from '@internal/server/ConfigurationChanges'\nimport { reconcileLocalAdministrator } from '@internal/auth/LocalDevelopment'\nimport { loadCmsConfiguration } from './cms-config'\nimport {\n cmsRuntimeConfigurationDefaults,\n cmsRuntimeConfigurationFromEnvironment,\n compileCmsConfiguration,\n resolveCmsInstallation,\n} from './configuration'\nimport { installCms, scopedDatabaseUrl } from '../runtime/installation'\nimport type { NuxtCmsInstallationOptions } from '../runtime/installation'\n\nexport type CmsDoctorStatus = 'pass' | 'fail' | 'not-verified'\n\nexport interface CmsDoctorCheck {\n readonly id: string\n readonly label: string\n readonly phase: string\n readonly status: CmsDoctorStatus\n readonly detail?: string\n}\n\nexport interface CmsDoctorReport {\n readonly ok: boolean\n readonly checks: ReadonlyArray<CmsDoctorCheck>\n}\n\nexport interface CmsBootstrapOptions {\n readonly content?: string\n readonly email: string\n readonly name: string\n readonly password: string\n readonly publish: boolean\n readonly rootDir: string\n readonly envFile?: string\n readonly verbose?: boolean\n}\n\nexport interface CmsBootstrapReport {\n readonly administrator: 'created' | 'updated' | 'verified'\n readonly contentApplied: boolean\n}\n\nexport interface CmsResetOptions {\n readonly bootstrap?: Omit<CmsBootstrapOptions, 'rootDir'>\n readonly database: boolean\n readonly media: boolean\n readonly rootDir: string\n readonly envFile?: string\n readonly yes: boolean\n readonly verbose?: boolean\n}\n\nexport interface CmsResetReport {\n readonly executed: boolean\n readonly targets: ReadonlyArray<string>\n readonly bootstrapped: boolean\n}\n\nexport async function checkCmsConfiguration(\n rootDir: string,\n envFile?: string,\n verbose = false,\n): Promise<ConfigurationCheckReport> {\n const project = await inPhase('configuration.load', () => loadConfiguration(rootDir, envFile))\n const authoring = await inPhase('configuration.authoring', () => prepareAuthoring(rootDir, verbose))\n\n const resolved = inPhaseSync('configuration.compile', () =>\n resolveCmsInstallation(project.authored.configuration, project.runtime, authoring),\n )\n\n const pool = new Pool({ connectionString: resolved.database.url })\n\n try {\n const pending = await inPhase('configuration.migrations', () => verifyMigrations(pool, resolved.database.schema))\n\n if (pending > 0)\n throw new CmsLifecycleFailed({\n cause: new Error(`${pending} database migration${pending === 1 ? ' is' : 's are'} pending.`),\n message: 'Run cms dev bootstrap before checking configuration changes.',\n phase: 'configuration.migrations',\n })\n } finally {\n await pool.end()\n }\n\n return inPhase('configuration.check', () =>\n Effect.runPromise(\n checkConfiguration(resolved.configuration, { documentModel: resolved.documentModel }).pipe(\n Effect.provide(\n postgresConfigurationCheckLayer({\n schema: resolved.database.schema,\n url: Redacted.make(resolved.database.url),\n }),\n ),\n ),\n ),\n )\n}\n\nconst nodeLayer = Layer.merge(NodeCrypto.layer, Layer.merge(NodeFileSystem.layer, NodePath.layer))\n\nconst InitializationStatus = Schema.Struct({ needsAdministrator: Schema.optionalKey(Schema.Boolean) })\n\nconst CauseCarrier = Schema.Struct({ cause: Schema.Unknown })\n\nclass CmsLifecycleFailed extends Schema.TaggedError<CmsLifecycleFailed>()('CmsLifecycleFailed', {\n cause: Schema.Defect(),\n message: Schema.String,\n phase: Schema.String,\n}) {}\n\nconst isCmsLifecycleFailed = Schema.is(CmsLifecycleFailed)\n\nexport async function doctorCmsDevelopment(rootDir: string, full = false, envFile?: string): Promise<CmsDoctorReport> {\n const checks: CmsDoctorCheck[] = []\n let configuration: NuxtCmsInstallationOptions\n\n try {\n const project = await loadConfiguration(rootDir, envFile)\n compileCmsConfiguration(project.authored.configuration)\n configuration = resolveCmsInstallation(project.authored.configuration, project.runtime, {\n revision: 'doctor',\n components: [],\n })\n checks.push(pass('configuration', 'Configuration loaded'))\n } catch (cause) {\n checks.push(fail('configuration', 'Configuration loaded', message(cause)))\n\n return report(checks)\n }\n\n const pool = new Pool({ connectionString: configuration.database.url })\n\n try {\n await pool.query('select 1')\n checks.push(pass('postgres', 'PostgreSQL reachable'))\n\n try {\n const pending = await verifyMigrations(pool, configuration.database.schema)\n checks.push(\n pending === 0\n ? pass('migrations', 'Database schema current')\n : fail(\n 'migrations',\n 'Database schema current',\n `${pending} migration${pending === 1 ? ' is' : 's are'} pending; run cms dev bootstrap.`,\n ),\n )\n } catch (cause) {\n checks.push(fail('migrations', 'Database schema current', message(cause)))\n }\n\n if (full) {\n await pool.query('begin')\n\n try {\n await pool.query(\n `create table \"${configuration.database.schema}\".\"__cms_doctor_${randomUUID().replaceAll('-', '')}\" (id integer)`,\n )\n checks.push(pass('postgres-write', 'PostgreSQL write access'))\n } finally {\n await pool.query('rollback')\n }\n } else {\n checks.push(notVerified('postgres-write', 'PostgreSQL write access', 'Use --full for a transient write check.'))\n }\n } catch (cause) {\n checks.push(fail('postgres', 'PostgreSQL reachable', message(cause)))\n } finally {\n await pool.end()\n }\n\n if (configuration.media === undefined) {\n checks.push(pass('s3', 'Media storage disabled'))\n } else {\n const storage = configuration.media\n const client = s3Client(storage)\n let publicProbeKey: string | undefined\n\n try {\n await client.send(new HeadBucketCommand({ Bucket: storage.bucket }))\n checks.push(pass('s3', 'S3 bucket reachable'))\n\n if (full) {\n const relativeKey = `.doctor/${randomUUID()}`\n const key = `${storage.prefix}${relativeKey}`\n await client.send(new PutObjectCommand({ Bucket: storage.bucket, Key: key, Body: new Uint8Array() }))\n publicProbeKey = key\n checks.push(pass('s3-write', 'S3 write access'))\n } else {\n checks.push(notVerified('s3-write', 'S3 write access', 'Use --full for a transient write check.'))\n }\n } catch (cause) {\n checks.push(fail('s3', 'S3 bucket reachable', message(cause)))\n }\n\n try {\n if (full && !publicProbeKey) {\n checks.push(notVerified('media-url', 'Public media URL reachable', 'The transient S3 upload failed.'))\n } else {\n const url = publicProbeKey\n ? publicObjectUrl(storage.publicBaseUrl, publicProbeKey.slice(storage.prefix.length))\n : new URL(storage.publicBaseUrl)\n\n const response = await fetch(url, { method: 'HEAD' })\n checks.push(\n response.ok || (!full && response.status === 404)\n ? pass('media-url', 'Public media URL reachable')\n : fail('media-url', 'Public media URL reachable', `${url.href} returned HTTP ${response.status}.`),\n )\n }\n } catch (cause) {\n checks.push(fail('media-url', 'Public media URL reachable', message(cause)))\n } finally {\n if (publicProbeKey)\n try {\n await client.send(new DeleteObjectCommand({ Bucket: storage.bucket, Key: publicProbeKey }))\n } catch (cause) {\n checks.push(fail('s3-cleanup', 'S3 doctor cleanup', message(cause)))\n }\n\n client.destroy()\n }\n }\n\n const bundledStudio = new URL('../studio/host.js', import.meta.url)\n const publishedStudio = new URL('../../studio/host.js', import.meta.url)\n const workspaceStudio = new URL('../../../../apps/studio/dist/host.js', import.meta.url)\n checks.push(\n existsSync(bundledStudio) || existsSync(publishedStudio) || existsSync(workspaceStudio)\n ? pass('assets', 'CMS and Studio package assets complete')\n : fail('assets', 'CMS and Studio package assets complete', 'Run the package build before publishing.'),\n )\n\n try {\n const readiness = await fetch(new URL(CMS_READINESS_PATH, configuration.baseUrl), {\n signal: AbortSignal.timeout(2_000),\n })\n\n checks.push(\n readiness.ok\n ? pass('server', 'Running server readiness')\n : fail('server', 'Running server readiness', `Returned HTTP ${readiness.status}.`),\n )\n\n if (readiness.ok) {\n try {\n await probeWebSocket(new URL(STUDIO_COLLABORATION_PATH, configuration.baseUrl))\n checks.push(pass('websocket', 'Running server WebSocket support'))\n } catch (cause) {\n checks.push(fail('websocket', 'Running server WebSocket support', message(cause)))\n }\n } else {\n checks.push(notVerified('websocket', 'Running server WebSocket support', 'Readiness did not succeed.'))\n }\n } catch {\n checks.push(notVerified('server', 'Running server readiness', 'Start Nuxt to verify the readiness endpoint.'))\n checks.push(notVerified('websocket', 'Running server WebSocket support', 'Start Nuxt to verify WebSockets.'))\n }\n\n return report(checks)\n}\n\nexport async function bootstrapCmsDevelopment(options: CmsBootstrapOptions): Promise<CmsBootstrapReport> {\n if (!options.email || !options.password) throw new Error('CMS_EMAIL and CMS_PASSWORD are required for bootstrap.')\n const project = await inPhase('bootstrap.configuration', () => loadConfiguration(options.rootDir, options.envFile))\n const authoring = await inPhase('bootstrap.authoring', () => prepareAuthoring(options.rootDir, options.verbose))\n\n const resolved = inPhaseSync('bootstrap.configuration', () =>\n resolveCmsInstallation(project.authored.configuration, project.runtime, authoring),\n )\n\n const installation = await inPhase('bootstrap.installation', () =>\n Effect.runPromise(\n installCms(resolved).pipe(Effect.provideService(References.MinimumLogLevel, options.verbose ? 'Info' : 'None')),\n ),\n )\n\n const localFetch: typeof globalThis.fetch = (input, init) => {\n const request = input instanceof Request ? new Request(input, init) : new Request(input, init)\n const headers = new Headers(request.headers)\n headers.set('x-forwarded-for', '127.0.0.1')\n\n return installation.fetch(new Request(request, { headers }))\n }\n\n try {\n const status = await inPhase('bootstrap.initialization', () =>\n localFetch(new URL(`${STUDIO_API_PATH}/initialization`, resolved.baseUrl)),\n )\n\n const state = await inPhase('bootstrap.initialization', async () =>\n Result.getOrThrow(Schema.decodeUnknownResult(InitializationStatus)(await status.json())),\n )\n\n let initialized = false\n\n if (state.needsAdministrator) {\n const claimed = await inPhase('bootstrap.initialization', () =>\n localFetch(new URL(`${STUDIO_API_PATH}/initialization`, resolved.baseUrl), {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n email: options.email,\n initializationToken: resolved.initializationToken,\n name: options.name,\n password: options.password,\n }),\n }),\n )\n\n if (!claimed.ok)\n throw new CmsLifecycleFailed({\n cause: new Error(`Administrator initialization failed (${claimed.status}).`),\n message: `Administrator initialization failed (${claimed.status}).`,\n phase: 'bootstrap.initialization',\n })\n initialized = true\n }\n\n const administrator = initialized\n ? 'created'\n : await inPhase('bootstrap.administrator', () =>\n reconcileAdministrator(resolved, {\n email: options.email,\n name: options.name,\n password: options.password,\n }),\n )\n\n const content = createCmsContentClient({\n baseUrl: resolved.baseUrl,\n credentials: { email: options.email, password: options.password },\n fetch: localFetch,\n })\n\n if (!options.content) {\n await inPhase('bootstrap.content', () => content.diff({ sources: [] }))\n\n return { administrator, contentApplied: false }\n }\n\n const contentDirectory = options.content\n const source = await inPhase('bootstrap.content', () => readCmsContentDirectory(contentDirectory))\n\n const plan = await inPhase('bootstrap.content', () =>\n content.plan(source, { overwrite: true, publish: options.publish }),\n )\n\n if (!plan.valid) {\n const details = [\n ...plan.conflicts.map((entry) => `${entry.filePath}: conflicts with the current CMS content`),\n ...plan.issues.map(\n (issue) =>\n `${issue.documentId ?? issue.key ?? 'content'}${issue.field ? ` (${issue.field})` : ''}: ${issue.message}`,\n ),\n ]\n\n throw new CmsLifecycleFailed({\n cause: new Error(`Bootstrap content has conflicts or validation errors. ${details.join(' ')}`),\n message: `Bootstrap content has conflicts or validation errors. ${details.join(' ')}`,\n phase: 'bootstrap.content',\n })\n }\n\n await inPhase('bootstrap.content', () => content.apply(plan))\n\n return { administrator, contentApplied: true }\n } finally {\n await installation.close()\n }\n}\n\nasync function reconcileAdministrator(\n configuration: NuxtCmsInstallationOptions,\n administrator: Pick<CmsBootstrapOptions, 'email' | 'name' | 'password'>,\n): Promise<CmsBootstrapReport['administrator']> {\n const pool = new Pool({ connectionString: scopedDatabaseUrl(configuration.database) })\n\n try {\n return await Effect.runPromise(\n reconcileLocalAdministrator({\n baseUrl: configuration.baseUrl,\n database: pool,\n email: administrator.email,\n name: administrator.name,\n password: administrator.password,\n secret: `cms-authentication:${configuration.secret}`,\n }),\n )\n } finally {\n await pool.end()\n }\n}\n\nexport async function resetCmsDevelopment(options: CmsResetOptions): Promise<CmsResetReport> {\n const project = await inPhase('reset.configuration', () => loadConfiguration(options.rootDir, options.envFile))\n\n const configuration = inPhaseSync('reset.configuration', () =>\n resolveCmsInstallation(project.authored.configuration, project.runtime, {\n revision: 'reset',\n components: [],\n }),\n )\n\n const targets = [\n ...(options.database ? [`PostgreSQL schema ${configuration.database.schema}`] : []),\n ...(options.media && configuration.media !== undefined\n ? [`S3 prefix ${configuration.media.bucket}/${configuration.media.prefix}`]\n : []),\n ]\n\n if (!options.yes) return { executed: false, targets, bootstrapped: false }\n await inPhase('reset.safety', () => refuseRunningInstallation(configuration.baseUrl))\n\n if (options.database) await inPhase('reset.database', () => resetDatabase(configuration.database))\n\n const media = configuration.media\n\n if (options.media && media !== undefined) await inPhase('reset.media', () => resetMedia(media))\n\n if (options.bootstrap)\n await bootstrapCmsDevelopment({\n rootDir: options.rootDir,\n envFile: options.envFile,\n verbose: options.verbose,\n ...options.bootstrap,\n })\n\n return { executed: true, targets, bootstrapped: options.bootstrap !== undefined }\n}\n\nexport async function loadCmsProjectEnvironment(rootDir: string, envFile?: string): Promise<void> {\n await setupDotenv({ cwd: resolve(rootDir), fileName: envFile ? ['.env', envFile] : '.env' })\n}\n\nasync function loadConfiguration(rootDir: string, envFile?: string) {\n const absoluteRoot = resolve(rootDir)\n await loadCmsProjectEnvironment(absoluteRoot, envFile)\n const authored = await Effect.runPromise(loadCmsConfiguration(absoluteRoot).pipe(Effect.provide(nodeLayer)))\n const nuxt = await loadNuxtConfig({ cwd: absoluteRoot, dotenv: false })\n const defaults = cmsRuntimeConfigurationDefaults(authored.configuration, nuxt.runtimeConfig.cms)\n const runtime = await Effect.runPromise(cmsRuntimeConfigurationFromEnvironment(defaults))\n\n return { authored, runtime }\n}\n\nasync function prepareAuthoring(rootDir: string, verbose = false): Promise<AuthoringCatalog> {\n const nuxt = await loadNuxt({\n cwd: rootDir,\n dev: true,\n ready: true,\n overrides: {\n logLevel: verbose ? 'verbose' : 'silent',\n ...(verbose ? undefined : { devtools: { enabled: false }, seo: { metaDataFiles: false } }),\n },\n })\n\n try {\n const source = (await readFile(resolve(nuxt.options.buildDir, 'cms/authoring.mjs'), 'utf8'))\n .replace(/^export default /u, '')\n .trim()\n\n return Result.getOrThrow(Schema.decodeUnknownResult(AuthoringCatalogSchema)(JSON.parse(source)))\n } finally {\n await nuxt.close()\n }\n}\n\nasync function refuseRunningInstallation(baseUrl: string): Promise<void> {\n try {\n await fetch(new URL(CMS_READINESS_PATH, baseUrl), { signal: AbortSignal.timeout(1_000) })\n throw new Error('Refusing to reset while the CMS server is running.')\n } catch (cause) {\n if (cause instanceof Error && cause.message.startsWith('Refusing')) throw cause\n }\n}\n\nasync function verifyMigrations(pool: Pool, schema: string): Promise<number> {\n const ledger = await pool.query<{ exists: boolean }>(\n 'select exists(select 1 from information_schema.tables where table_schema = $1 and table_name = $2) as exists',\n [schema, '__drizzle_migrations'],\n )\n\n const applied = ledger.rows[0]?.exists\n ? (\n await pool.query<{ createdAt: string; hash: string }>(\n `select created_at as \"createdAt\", hash from \"${schema}\".\"__drizzle_migrations\" order by created_at`,\n )\n ).rows\n : []\n\n const matches = applied.every(\n (migration, index) =>\n migration.hash === postgresMigrations[index]?.hash &&\n Number(migration.createdAt) === postgresMigrations[index]?.createdAt,\n )\n\n if (!matches || applied.length > postgresMigrations.length)\n throw new Error('The applied migration history does not match this CMS release.')\n\n const pending = postgresMigrations.slice(applied.length)\n const connection = await pool.connect()\n\n try {\n await connection.query('begin')\n await connection.query(`create schema if not exists \"${schema}\"`)\n await connection.query(`set local search_path to \"${schema}\"`)\n\n for (const migration of pending) for (const statement of migration.statements) await connection.query(statement)\n } finally {\n await connection.query('rollback')\n connection.release()\n }\n\n return pending.length\n}\n\nfunction publicObjectUrl(baseUrl: string, key: string): URL {\n const base = new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`)\n\n return new URL(key.split('/').map(encodeURIComponent).join('/'), base)\n}\n\nasync function probeWebSocket(httpUrl: URL): Promise<void> {\n const url = new URL(httpUrl)\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'\n\n await new Promise<void>((resolve, reject) => {\n const socket = new WebSocket(url)\n\n const timeout = setTimeout(() => {\n socket.close()\n reject(new Error('The WebSocket handshake timed out.'))\n }, 2_000)\n\n socket.addEventListener('open', () => {\n clearTimeout(timeout)\n socket.close()\n resolve()\n })\n socket.addEventListener('error', () => {\n clearTimeout(timeout)\n reject(new Error(`Could not open ${url.href}.`))\n })\n })\n}\n\nasync function resetDatabase(database: NuxtCmsInstallationOptions['database']): Promise<void> {\n const pool = new Pool({ connectionString: database.url })\n\n try {\n const client = await pool.connect()\n\n try {\n await client.query('select pg_advisory_lock(hashtextextended($1, 0))', ['cms:development-reset:v1'])\n await client.query(`drop schema if exists \"${database.schema}\" cascade`)\n await client.query(`create schema \"${database.schema}\"`)\n } finally {\n client.release()\n }\n } finally {\n await pool.end()\n }\n}\n\nasync function resetMedia(storage: NonNullable<NuxtCmsInstallationOptions['media']>): Promise<void> {\n const client = s3Client(storage)\n\n try {\n let continuationToken: string | undefined\n\n do {\n const page = await client.send(\n new ListObjectsV2Command({\n Bucket: storage.bucket,\n Prefix: storage.prefix,\n ContinuationToken: continuationToken,\n }),\n )\n\n for (const object of page.Contents ?? [])\n if (object.Key) await client.send(new DeleteObjectCommand({ Bucket: storage.bucket, Key: object.Key }))\n continuationToken = page.IsTruncated ? page.NextContinuationToken : undefined\n } while (continuationToken)\n } finally {\n client.destroy()\n }\n}\n\nfunction s3Client(storage: NonNullable<NuxtCmsInstallationOptions['media']>): S3Client {\n return new S3Client({\n region: storage.region,\n endpoint: storage.endpoint,\n forcePathStyle: storage.forcePathStyle,\n credentials: storage.credentials,\n })\n}\n\nfunction pass(id: string, label: string): CmsDoctorCheck {\n return { id, label, phase: `doctor.${id}`, status: 'pass' }\n}\n\nfunction fail(id: string, label: string, detail: string): CmsDoctorCheck {\n return { id, label, phase: `doctor.${id}`, status: 'fail', detail }\n}\n\nfunction notVerified(id: string, label: string, detail: string): CmsDoctorCheck {\n return { id, label, phase: `doctor.${id}`, status: 'not-verified', detail }\n}\n\nfunction report(checks: ReadonlyArray<CmsDoctorCheck>): CmsDoctorReport {\n return { ok: checks.every((check) => check.status !== 'fail'), checks }\n}\n\nfunction message(cause: unknown): string {\n if (cause instanceof Error && cause.message) return cause.message\n\n if (Schema.is(CauseCarrier)(cause)) return message(cause.cause)\n\n return String(cause)\n}\n\nasync function inPhase<Value>(phase: string, operation: () => PromiseLike<Value>): Promise<Value> {\n try {\n return await operation()\n } catch (cause) {\n if (isCmsLifecycleFailed(cause)) throw cause\n throw new CmsLifecycleFailed({ cause, message: message(cause), phase })\n }\n}\n\nfunction inPhaseSync<Value>(phase: string, operation: () => Value): Value {\n try {\n return operation()\n } catch (cause) {\n if (isCmsLifecycleFailed(cause)) throw cause\n throw new CmsLifecycleFailed({ cause, message: message(cause), phase })\n }\n}\n"],"mappings":"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"}