@phtngyn/cms 0.2.0-beta.6 → 0.2.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -0
- package/README.md +7 -4
- package/package.json +1 -1
- package/src/ApplicationTypes.d.ts +1 -1
- package/src/{Configuration-JQ1qyaU0.js → Configuration-CMweD9bn.js} +3 -3
- package/src/{Configuration-JQ1qyaU0.js.map → Configuration-CMweD9bn.js.map} +1 -1
- package/src/Configuration.d.ts +1 -1
- package/src/Content.js +4 -4
- package/src/Content.js.map +1 -1
- package/src/{DocumentEngine-j6Vi7nQo.js → DocumentEngine-tYtwbBjr.js} +7 -7
- package/src/DocumentEngine-tYtwbBjr.js.map +1 -0
- package/src/{HttpPaths-c9nLZ9H2.js → HttpPaths-Be3vshPJ.js} +2 -3
- package/src/HttpPaths-Be3vshPJ.js.map +1 -0
- package/src/{I18n-zbqpWxki.d.ts → I18n-wxswIRyY.d.ts} +3 -2
- package/src/I18n.d.ts +1 -1
- package/src/Module.js +2 -13
- package/src/Module.js.map +1 -1
- package/src/{S3MediaObjects-BRuPQbxl.js → S3MediaObjects-BXfjaZOu.js} +20 -6
- package/src/S3MediaObjects-BXfjaZOu.js.map +1 -0
- package/src/cli.js +3 -3
- package/src/{dev-lifecycle-CExksm2R.js → dev-lifecycle-3I_pozUl.js} +8 -8
- package/src/dev-lifecycle-3I_pozUl.js.map +1 -0
- package/src/{installation-BoG8E3nJ.js → installation-DxqSSVbH.js} +11 -22
- package/src/installation-DxqSSVbH.js.map +1 -0
- package/src/internal/authoring-catalog.js +1 -1
- package/src/internal/authoring-metadata.js +1 -1
- package/src/internal/configuration.js +1 -1
- package/src/internal/dev-lifecycle.js +1 -1
- package/src/internal/document-model.js +3 -3
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/i18n.js +2 -2
- package/src/internal/i18n.js.map +1 -1
- package/src/internal/studio-app.js +3 -3
- package/src/internal/studio-app.js.map +1 -1
- package/src/{metadata-UzZmjwxM.js → metadata-DN9_K6Yl.js} +87 -7
- package/src/metadata-DN9_K6Yl.js.map +1 -0
- package/src/runtime/delivery/plugin.js +7 -2
- package/src/runtime/delivery/plugin.js.map +1 -1
- package/src/runtime/delivery/useDocument.js +1 -1
- package/src/runtime/delivery/useDocumentQuery.js +1 -1
- package/src/runtime/forms/useCmsForm.js +1 -1
- package/src/runtime/i18n/translator.js +10 -3
- package/src/runtime/i18n/translator.js.map +1 -1
- package/src/runtime/i18n/useCmsI18n.d.ts +1 -1
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +1 -1
- package/src/runtime/preview/controller.js +3 -2
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/crypto.js +16 -0
- package/src/runtime/preview/crypto.js.map +1 -0
- package/src/runtime/preview/plugin.client.js +1 -1
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +1 -1
- package/src/runtime/studio-app.js +1 -1
- package/src/runtime/studio-app.js.map +1 -1
- package/src/runtime/studio-document.js +46 -0
- package/src/runtime/studio-document.js.map +1 -0
- package/src/runtime/studio-entry.js +5 -22
- package/src/runtime/studio-entry.js.map +1 -1
- package/src/runtime/studio-navigation.js +2 -2
- package/src/runtime/studio-navigation.js.map +1 -1
- package/src/{store-PKKB8xa2.js → store-X1e1o_MF.js} +2 -2
- package/src/{store-PKKB8xa2.js.map → store-X1e1o_MF.js.map} +1 -1
- package/studio/{CreateDocumentDialog-DqvusuGU.js → CreateDocumentDialog-C4_JBo1w.js} +90 -90
- package/studio/{SelectMenu-BgikeouH.js → SelectMenu-wXqxymUw.js} +8626 -8496
- package/studio/host.js +4244 -4151
- package/src/DocumentEngine-j6Vi7nQo.js.map +0 -1
- package/src/HttpPaths-c9nLZ9H2.js.map +0 -1
- package/src/S3MediaObjects-BRuPQbxl.js.map +0 -1
- package/src/dev-lifecycle-CExksm2R.js.map +0 -1
- package/src/installation-BoG8E3nJ.js.map +0 -1
- package/src/metadata-UzZmjwxM.js.map +0 -1
package/src/Content.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Content.js","names":["ContentSnapshotSchema","ContentSourceSchema","ProtocolContentPlanSchema","ContentApplyResultSchema","ContentSnapshotSourceSchema"],"sources":["../../../src/Content.ts"],"sourcesContent":["/* oxlint-disable effecttsgo/async-function effecttsgo/extends-native-error effecttsgo/node-builtin-import -- This public Node-only API deliberately exposes Promises, native filesystem paths, and an Error subclass to ordinary deployment scripts. */\nimport type {\n ContentApplyResult,\n ContentPlan as ProtocolContentPlan,\n ContentPlanEntry,\n ContentSnapshotSource,\n ContentSource,\n ContentSnapshot,\n} from '@internal/protocol/ContentTransfer'\nimport {\n ContentApplyResult as ContentApplyResultSchema,\n ContentFilePath,\n ContentPlan as ProtocolContentPlanSchema,\n ContentSnapshotSource as ContentSnapshotSourceSchema,\n ContentSource as ContentSourceSchema,\n ContentSnapshot as ContentSnapshotSchema,\n} from '@internal/protocol/ContentTransfer'\nimport type { DocumentIssue } from '@internal/protocol/Documents'\nimport { DocumentIdentity, DocumentPlacement, DocumentValidationFailed } from '@internal/protocol/Documents'\nimport { CMS_AUTHENTICATION_PATH, STUDIO_API_PATH } from '@internal/protocol/HttpPaths'\nimport { Result, Schema } from 'effect'\nimport { createHash } from 'node:crypto'\nimport { lstat, readdir, readFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname, extname, relative, resolve, sep } from 'node:path'\n\nexport type CmsContentErrorCode =\n | 'authentication-required'\n | 'content-conflict'\n | 'filesystem-error'\n | 'generation-changed'\n | 'invalid-document'\n | 'document-not-found'\n | 'invalid-response'\n | 'network-error'\n\nexport class CmsContentError extends Error {\n readonly code: CmsContentErrorCode\n readonly conflicts?: ReadonlyArray<CmsContentPlanEntry>\n readonly issues?: ReadonlyArray<DocumentIssue>\n\n constructor(\n code: CmsContentErrorCode,\n message: string,\n options: {\n readonly cause?: unknown\n readonly conflicts?: ReadonlyArray<CmsContentPlanEntry>\n readonly issues?: ReadonlyArray<DocumentIssue>\n } = {},\n ) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause })\n this.name = 'CmsContentError'\n this.code = code\n this.conflicts = options.conflicts\n this.issues = options.issues\n }\n}\n\nexport interface CmsContentCredentials {\n readonly email: string\n readonly password: string\n}\n\nexport interface CmsContentClientOptions {\n readonly baseUrl: string\n readonly credentials: CmsContentCredentials\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport interface CmsContentSourceSet {\n readonly sources: ReadonlyArray<ContentSource>\n}\n\nexport interface CmsContentDocument extends ContentSnapshotSource {}\n\nexport interface CmsContentPlanEntry extends ContentPlanEntry {}\n\nexport interface CmsContentPlan {\n readonly generation: string\n readonly creates: ReadonlyArray<CmsContentPlanEntry>\n readonly updates: ReadonlyArray<CmsContentPlanEntry>\n readonly publications: ReadonlyArray<CmsContentPlanEntry>\n readonly unpublications: ReadonlyArray<CmsContentPlanEntry>\n readonly conflicts: ReadonlyArray<CmsContentPlanEntry>\n readonly unchanged: ReadonlyArray<CmsContentPlanEntry>\n readonly issues: ReadonlyArray<DocumentIssue>\n readonly targetOnly: ReadonlyArray<ContentSnapshotSource>\n readonly valid: boolean\n}\n\nexport interface CmsContentImportOptions {\n readonly overwrite?: boolean\n readonly publish?: boolean\n}\n\nexport interface CmsContentDiff {\n readonly changes: ReadonlyArray<{\n readonly filePath: string\n readonly local?: ContentSource\n readonly target?: ContentSource | ContentSnapshotSource\n readonly markdownChanged: boolean\n readonly publicationChanged: boolean\n }>\n readonly targetOnly: ReadonlyArray<ContentSource | ContentSnapshotSource>\n}\n\nexport interface CmsContentClient {\n readonly plan: (source: CmsContentSourceSet, options?: CmsContentImportOptions) => Promise<CmsContentPlan>\n readonly apply: (plan: CmsContentPlan) => Promise<ContentApplyResult>\n readonly diff: (source: CmsContentSourceSet) => Promise<CmsContentDiff>\n readonly export: (options: { readonly directory: string }) => Promise<CmsContentSourceSet>\n readonly readDocument: (documentId: string) => Promise<CmsContentDocument>\n}\n\ninterface PlanState {\n readonly client: object\n readonly input: {\n readonly sources: ReadonlyArray<ContentSource>\n readonly overwrite: boolean\n readonly publish: boolean\n }\n readonly protocol: ProtocolContentPlan\n}\n\ntype CmsContentRequestBody =\n | PlanState['input']\n | (PlanState['input'] & { readonly expectedGeneration: ProtocolContentPlan['generation'] })\n\nconst plans = new WeakMap<CmsContentPlan, PlanState>()\n\nexport function createCmsContentClient(options: CmsContentClientOptions): CmsContentClient {\n const baseUrl = contentBaseUrl(options.baseUrl)\n const requestFetch = options.fetch ?? globalThis.fetch\n const identity = {}\n let cookie: Promise<string> | undefined\n\n const authenticate = async (): Promise<string> => {\n if (cookie) return cookie\n\n cookie = request(requestFetch, new URL(`${CMS_AUTHENTICATION_PATH}/sign-in/email`, baseUrl), {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json', origin: baseUrl.origin },\n body: JSON.stringify(options.credentials),\n }).then(async (response) => {\n if (!response.ok) throw new CmsContentError('authentication-required', `CMS sign-in failed (${response.status}).`)\n const value = response.headers.get('set-cookie')?.split(';', 1)[0]\n\n if (!value) throw new CmsContentError('authentication-required', 'CMS sign-in did not return a session cookie.')\n\n return value\n })\n\n return cookie\n }\n\n const contentRequest = async <SchemaType extends Schema.ConstraintDecoder<unknown>>(\n path: string,\n schema: SchemaType,\n label: string,\n body?: CmsContentRequestBody,\n ): Promise<SchemaType['Type']> => {\n const session = await authenticate()\n\n const response = await request(requestFetch, new URL(`${STUDIO_API_PATH}/content/${path}`, baseUrl), {\n method: body === undefined ? 'GET' : 'POST',\n headers: {\n accept: 'application/json',\n cookie: session,\n ...(body === undefined ? undefined : { 'content-type': 'application/json' }),\n },\n ...(body === undefined ? undefined : { body: JSON.stringify(body) }),\n })\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403)\n throw new CmsContentError('authentication-required', `CMS content request was rejected (${response.status}).`)\n\n if (response.status === 409)\n throw new CmsContentError('generation-changed', 'The CMS changed after this content plan was created.')\n\n if (response.status === 422) {\n const failure = await decodeResponse(response, DocumentValidationFailed, 'document validation failure')\n\n throw new CmsContentError('invalid-document', 'The CMS rejected an invalid document.', {\n issues: failure.issues,\n })\n }\n\n throw new CmsContentError('network-error', `CMS content request failed (${response.status}).`)\n }\n\n return decodeResponse(response, schema, label)\n }\n\n const snapshot = async (): Promise<ContentSnapshot> =>\n contentRequest('snapshot', ContentSnapshotSchema, 'content snapshot')\n\n const client: CmsContentClient = {\n plan: async (source, authoredOptions = {}) => {\n const sources = Object.freeze(\n source.sources.map((entry) =>\n Object.freeze(\n ContentSourceSchema.make({\n filePath: entry.filePath,\n ...(entry.identity === undefined ? undefined : { identity: entry.identity }),\n markdown: entry.markdown,\n ...(entry.placement === undefined ? undefined : { placement: entry.placement }),\n published: entry.published,\n }),\n ),\n ),\n )\n\n const input = Object.freeze({\n sources,\n overwrite: authoredOptions.overwrite ?? false,\n publish: authoredOptions.publish ?? false,\n })\n\n const [protocol, current] = await Promise.all([\n contentRequest('plan', ProtocolContentPlanSchema, 'content plan', input),\n snapshot(),\n ])\n\n const documentIds = new Set(sources.flatMap((entry) => (entry.identity ? [entry.identity.documentId] : [])))\n\n const entries = (action: ContentPlanEntry['action']) =>\n protocol.entries.filter((entry) => entry.action === action)\n\n const plan: CmsContentPlan = Object.freeze({\n generation: protocol.generation,\n creates: entries('create'),\n updates: entries('update'),\n publications: entries('publish'),\n unpublications: entries('unpublish'),\n conflicts: entries('conflict'),\n unchanged: entries('unchanged'),\n issues: protocol.issues,\n targetOnly: current.sources.filter((entry) => !documentIds.has(entry.identity.documentId)),\n valid: protocol.valid,\n })\n\n plans.set(plan, { client: identity, input, protocol })\n\n return plan\n },\n apply: async (plan) => {\n const state = plans.get(plan)\n\n if (!state || state.client !== identity)\n throw new CmsContentError('content-conflict', 'This content plan was not created by this client.')\n\n if (!plan.valid)\n throw new CmsContentError('content-conflict', 'The content plan is not valid.', {\n conflicts: plan.conflicts,\n issues: plan.issues,\n })\n\n if (plan.conflicts.length)\n throw new CmsContentError('content-conflict', 'The content plan contains conflicts.', {\n conflicts: plan.conflicts,\n })\n\n if (plan.issues.length)\n throw new CmsContentError('invalid-document', 'The content plan contains invalid documents.', {\n issues: plan.issues,\n })\n\n return contentRequest('apply', ContentApplyResultSchema, 'content apply result', {\n ...state.input,\n expectedGeneration: state.protocol.generation,\n })\n },\n diff: async (source) => diffSources(source.sources, (await snapshot()).sources),\n export: async ({ directory }) => {\n const value = await snapshot()\n\n return writeContentDirectory(directory, value.sources)\n },\n readDocument: async (documentId) => {\n const document = (await snapshot()).sources.find((source) => source.identity.documentId === documentId)\n\n if (!document) throw new CmsContentError('document-not-found', `CMS document ${documentId} was not found.`)\n\n return document\n },\n }\n\n return client\n}\n\nexport async function readCmsContentDirectory(directory: string): Promise<CmsContentSourceSet> {\n try {\n const root = resolve(directory)\n const indexPath = await safeContentFile(root, '.cms-content.json')\n let index: ContentIndex | undefined\n\n try {\n index = parseIndex(await readFile(indexPath, 'utf8'))\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n\n if (index) {\n const sources = await Promise.all(\n index.sources.map(async (entry) =>\n decode(\n ContentSourceSchema,\n {\n filePath: entry.filePath,\n identity: entry.identity,\n markdown: await readFile(await safeContentFile(root, entry.filePath), 'utf8'),\n placement: entry.placement,\n published: entry.published,\n revisionId: entry.revisionId,\n },\n 'content source',\n ),\n ),\n )\n\n return { sources }\n }\n\n const files = await markdownFiles(root)\n\n if (!files.length) throw new CmsContentError('filesystem-error', `No Markdown files found in ${root}.`)\n\n return {\n sources: await Promise.all(\n files.map(async (file) =>\n decode(\n ContentSourceSchema,\n {\n filePath: relative(root, file).replaceAll('\\\\', '/'),\n markdown: await readFile(file, 'utf8'),\n published: true,\n },\n 'content source',\n ),\n ),\n ),\n }\n } catch (cause) {\n if (cause instanceof CmsContentError) throw cause\n throw new CmsContentError('filesystem-error', `Could not read CMS content from ${directory}.`, { cause })\n }\n}\n\nexport function diffCmsContentSources(\n local: ReadonlyArray<ContentSource>,\n target: ReadonlyArray<ContentSource | ContentSnapshotSource>,\n): CmsContentDiff {\n return diffSources(local, target)\n}\n\nconst ContentHash = Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/u))\n\nconst ContentIndexEntry = Schema.Struct({\n filePath: ContentSourceSchema.fields.filePath,\n identity: DocumentIdentity,\n placement: DocumentPlacement,\n published: Schema.Boolean,\n revisionId: ContentSnapshotSourceSchema.fields.revisionId,\n sha256: ContentHash,\n})\n\nconst ContentIndex = Schema.Struct({\n version: Schema.Literal(2),\n sources: Schema.Array(ContentIndexEntry),\n exportSha256: ContentHash,\n})\n\ntype ContentIndex = typeof ContentIndex.Type\n\ntype ContentIndexEntry = typeof ContentIndexEntry.Type\n\nasync function writeContentDirectory(\n directory: string,\n sources: ReadonlyArray<ContentSnapshotSource>,\n): Promise<CmsContentSourceSet> {\n try {\n const root = resolve(directory)\n const indexPath = await safeContentFile(root, '.cms-content.json')\n let previous: ContentIndex | undefined\n\n try {\n previous = parseIndex(await readFile(indexPath, 'utf8'))\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n\n const previousById = new Map(previous?.sources.map((entry) => [entry.identity.documentId, entry]))\n const paths = exportPaths(sources, previousById)\n\n if (previous) {\n const metadata = { version: previous.version, sources: previous.sources }\n\n if (sha256(JSON.stringify(metadata)) !== previous.exportSha256)\n throw new CmsContentError('filesystem-error', 'The local .cms-content.json file has been edited.')\n\n const incomingIds = new Set(sources.map((source) => source.identity.documentId))\n\n for (const entry of previous.sources)\n if (!incomingIds.has(entry.identity.documentId))\n throw new CmsContentError(\n 'filesystem-error',\n `CMS document ${entry.filePath} no longer exists; resolve the local file before exporting again.`,\n )\n }\n\n for (const source of sources) {\n const filePath = paths.get(source.identity.documentId)\n\n if (!filePath)\n throw new CmsContentError(\n 'filesystem-error',\n `Could not allocate an export path for ${source.identity.documentId}.`,\n )\n\n try {\n const local = await readFile(await safeContentFile(root, filePath), 'utf8')\n const before = previousById.get(source.identity.documentId)\n\n if (before ? sha256(local) !== before.sha256 : local !== source.markdown)\n throw new CmsContentError('filesystem-error', `Local edits in ${filePath}; export was stopped.`)\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n }\n\n await mkdir(root, { recursive: true })\n const entries: ContentIndexEntry[] = []\n\n for (const source of sources) {\n const filePath = paths.get(source.identity.documentId)\n\n if (!filePath)\n throw new CmsContentError(\n 'filesystem-error',\n `Could not allocate an export path for ${source.identity.documentId}.`,\n )\n const file = await safeContentFile(root, filePath)\n await mkdir(dirname(file), { recursive: true })\n await safeContentFile(root, filePath)\n await writeFile(file, source.markdown)\n entries.push({\n filePath,\n identity: source.identity,\n placement: source.placement,\n published: source.published,\n revisionId: source.revisionId,\n sha256: sha256(source.markdown),\n })\n }\n\n const metadata = { version: 2 as const, sources: entries }\n const index: ContentIndex = { ...metadata, exportSha256: sha256(JSON.stringify(metadata)) }\n await safeContentFile(root, '.cms-content.json')\n await writeFile(indexPath, `${JSON.stringify(index, undefined, 2)}\\n`)\n\n return {\n sources: sources.map((source) =>\n ContentSourceSchema.make({\n filePath: paths.get(source.identity.documentId)!,\n identity: source.identity,\n markdown: source.markdown,\n placement: source.placement,\n published: source.published,\n revisionId: source.revisionId,\n }),\n ),\n }\n } catch (cause) {\n throw new CmsContentError('filesystem-error', `Could not export CMS content to ${directory}.`, { cause })\n }\n}\n\nfunction diffSources(\n local: ReadonlyArray<ContentSource>,\n target: ReadonlyArray<ContentSource | ContentSnapshotSource>,\n): CmsContentDiff {\n const targetById = new Map(\n target.flatMap((source) => (source.identity ? [[source.identity.documentId, source] as const] : [])),\n )\n\n const targetByFile = new Map(\n target.flatMap((source) => ('filePath' in source ? [[source.filePath, source] as const] : [])),\n )\n\n const localIds = new Set(local.flatMap((source) => (source.identity ? [source.identity.documentId] : [])))\n const localFiles = new Set(local.map((source) => source.filePath))\n\n return {\n changes: local.flatMap((source) => {\n const current = source.identity ? targetById.get(source.identity.documentId) : targetByFile.get(source.filePath)\n const markdownChanged = current?.markdown !== source.markdown\n const publicationChanged = current !== undefined && current.published !== source.published\n\n return markdownChanged || publicationChanged\n ? [{ filePath: source.filePath, local: source, target: current, markdownChanged, publicationChanged }]\n : []\n }),\n targetOnly: target.filter((source) =>\n source.identity\n ? !localIds.has(source.identity.documentId)\n : 'filePath' in source && !localFiles.has(source.filePath),\n ),\n }\n}\n\nfunction exportPaths(\n sources: ReadonlyArray<ContentSnapshotSource>,\n previous: ReadonlyMap<string, ContentIndexEntry>,\n): ReadonlyMap<string, ContentFilePath> {\n const byId = new Map(sources.map((source) => [source.identity.documentId, source]))\n const allocated = new Set<string>()\n const result = new Map<string, ContentFilePath>()\n\n const segmentsFor = (source: ContentSnapshotSource, visited = new Set<string>()): ReadonlyArray<string> => {\n if (source.placement.kind === 'home') return []\n\n if (visited.has(source.identity.documentId)) return [source.placement.slug]\n const parent = byId.get(source.placement.parentDocumentId)\n\n return parent\n ? [...segmentsFor(parent, new Set([...visited, source.identity.documentId])), source.placement.slug]\n : [source.placement.slug]\n }\n\n for (const source of sources) {\n const retained = previous.get(source.identity.documentId)?.filePath\n const base = [source.identity.collection, ...(source.identity.locale ? [source.identity.locale] : [])]\n const placement = segmentsFor(source)\n\n const generated =\n source.placement.kind === 'home'\n ? [...base, 'index.md'].join('/')\n : [...base, ...placement.slice(0, -1), `${placement.at(-1) ?? 'document'}.md`].join('/')\n\n let candidate = retained ?? ContentFilePath.make(generated)\n\n if (allocated.has(candidate)) {\n candidate = ContentFilePath.make(generated.replace(/\\.md$/u, `-${source.identity.documentId.slice(0, 8)}.md`))\n }\n\n allocated.add(candidate)\n result.set(source.identity.documentId, candidate)\n }\n\n return result\n}\n\nasync function markdownFiles(directory: string): Promise<ReadonlyArray<string>> {\n const entries = await readdir(directory, { withFileTypes: true })\n\n const nested = await Promise.all(\n entries.map(async (entry) => {\n const path = resolve(directory, entry.name)\n\n if (entry.isDirectory()) return markdownFiles(path)\n\n return entry.isFile() && ['.md', '.mdc'].includes(extname(path)) ? [path] : []\n }),\n )\n\n return nested.flat().sort((left, right) => left.localeCompare(right))\n}\n\nfunction safeContentPath(root: string, filePath: string): string {\n const path = resolve(root, filePath)\n\n if (!path.startsWith(`${root}${sep}`))\n throw new CmsContentError('filesystem-error', `Unsafe content path: ${filePath}`)\n\n return path\n}\n\nasync function safeContentFile(root: string, filePath: string): Promise<string> {\n const path = safeContentPath(root, filePath)\n const segments = relative(root, path).split(sep)\n let current = root\n\n for (const segment of ['', ...segments]) {\n current = segment ? resolve(current, segment) : current\n\n try {\n if ((await lstat(current)).isSymbolicLink())\n throw new CmsContentError('filesystem-error', `Symlinks are not allowed in CMS content paths: ${filePath}`)\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n }\n\n return path\n}\n\nfunction contentBaseUrl(value: string): URL {\n let url: URL\n\n try {\n url = new URL(value)\n } catch (cause) {\n throw new CmsContentError('network-error', 'CMS baseUrl is invalid.', { cause })\n }\n\n if (url.username || url.password || url.search || url.hash)\n throw new CmsContentError('network-error', 'CMS baseUrl must be an origin without credentials, query, or fragment.')\n\n if (\n url.protocol !== 'https:' &&\n !(url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname))\n )\n throw new CmsContentError('network-error', 'Use HTTPS for CMS credentials; HTTP is allowed only on localhost.')\n\n return new URL(url.origin)\n}\n\nasync function request(fetch: typeof globalThis.fetch, input: URL, init: RequestInit): Promise<Response> {\n try {\n return await fetch(input, init)\n } catch (cause) {\n throw new CmsContentError('network-error', `Could not reach ${input.origin}.`, { cause })\n }\n}\n\nasync function decodeResponse<SchemaType extends Schema.ConstraintDecoder<unknown>>(\n response: Response,\n schema: SchemaType,\n label: string,\n): Promise<SchemaType['Type']> {\n try {\n return decode(schema, await response.json(), label)\n } catch (cause) {\n if (cause instanceof CmsContentError) throw cause\n throw new CmsContentError('invalid-response', 'CMS returned an invalid JSON response.', { cause })\n }\n}\n\n/* oxlint-disable anti-slop/no-unknown-parameters -- Untrusted JSON and filesystem values enter their explicit Schema decoder here. */\nfunction decode<SchemaType extends Schema.ConstraintDecoder<unknown>>(\n schema: SchemaType,\n value: unknown,\n label: string,\n): SchemaType['Type'] {\n const decoded = Schema.decodeUnknownResult(schema)(value)\n\n if (Result.isFailure(decoded))\n throw new CmsContentError('invalid-response', `CMS returned an invalid ${label}.`, { cause: decoded.failure })\n\n return decoded.success\n}\n/* oxlint-enable anti-slop/no-unknown-parameters */\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex')\n}\n\nfunction parseIndex(value: string): ContentIndex {\n const decoded = Schema.decodeUnknownResult(ContentIndex)(JSON.parse(value))\n\n if (Result.isFailure(decoded))\n throw new CmsContentError('filesystem-error', 'The .cms-content.json index is invalid.')\n\n const filePaths = new Set(decoded.success.sources.map((entry) => entry.filePath))\n\n if (filePaths.size !== decoded.success.sources.length)\n throw new CmsContentError('filesystem-error', 'The .cms-content.json index contains duplicate file paths.')\n\n return decoded.success\n}\n\nfunction isMissingFile(cause: unknown): boolean {\n return cause instanceof Error && 'code' in cause && cause.code === 'ENOENT'\n}\n\nexport type { ContentApplyResult, ContentSource }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Content.js","names":["ContentSnapshotSchema","ContentSourceSchema","ProtocolContentPlanSchema","ContentApplyResultSchema","ContentSnapshotSourceSchema"],"sources":["../../../src/Content.ts"],"sourcesContent":["/* oxlint-disable effecttsgo/async-function effecttsgo/extends-native-error effecttsgo/node-builtin-import -- This public Node-only API deliberately exposes Promises, native filesystem paths, and an Error subclass to ordinary deployment scripts. */\nimport type {\n ContentApplyResult,\n ContentPlan as ProtocolContentPlan,\n ContentPlanEntry,\n ContentSnapshotSource,\n ContentSource,\n ContentSnapshot,\n} from '@internal/protocol/ContentTransfer'\nimport {\n ContentApplyResult as ContentApplyResultSchema,\n ContentFilePath,\n ContentPlan as ProtocolContentPlanSchema,\n ContentSnapshotSource as ContentSnapshotSourceSchema,\n ContentSource as ContentSourceSchema,\n ContentSnapshot as ContentSnapshotSchema,\n} from '@internal/protocol/ContentTransfer'\nimport type { DocumentIssue } from '@internal/protocol/Documents'\nimport { DocumentIdentity, DocumentPlacement, DocumentValidationFailed } from '@internal/protocol/Documents'\nimport { CMS_AUTHENTICATION_PATH, STUDIO_API_PATH } from '@internal/protocol/HttpPaths'\nimport { NodeCrypto } from '@effect/platform-node-shared'\nimport { Effect, Encoding, Result, Schema } from 'effect'\nimport { lstat, readdir, readFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname, extname, relative, resolve, sep } from 'node:path'\n\nexport type CmsContentErrorCode =\n | 'authentication-required'\n | 'content-conflict'\n | 'filesystem-error'\n | 'generation-changed'\n | 'invalid-document'\n | 'document-not-found'\n | 'invalid-response'\n | 'network-error'\n\nexport class CmsContentError extends Error {\n readonly code: CmsContentErrorCode\n readonly conflicts?: ReadonlyArray<CmsContentPlanEntry>\n readonly issues?: ReadonlyArray<DocumentIssue>\n\n constructor(\n code: CmsContentErrorCode,\n message: string,\n options: {\n readonly cause?: unknown\n readonly conflicts?: ReadonlyArray<CmsContentPlanEntry>\n readonly issues?: ReadonlyArray<DocumentIssue>\n } = {},\n ) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause })\n this.name = 'CmsContentError'\n this.code = code\n this.conflicts = options.conflicts\n this.issues = options.issues\n }\n}\n\nexport interface CmsContentCredentials {\n readonly email: string\n readonly password: string\n}\n\nexport interface CmsContentClientOptions {\n readonly baseUrl: string\n readonly credentials: CmsContentCredentials\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport interface CmsContentSourceSet {\n readonly sources: ReadonlyArray<ContentSource>\n}\n\nexport interface CmsContentDocument extends ContentSnapshotSource {}\n\nexport interface CmsContentPlanEntry extends ContentPlanEntry {}\n\nexport interface CmsContentPlan {\n readonly generation: string\n readonly creates: ReadonlyArray<CmsContentPlanEntry>\n readonly updates: ReadonlyArray<CmsContentPlanEntry>\n readonly publications: ReadonlyArray<CmsContentPlanEntry>\n readonly unpublications: ReadonlyArray<CmsContentPlanEntry>\n readonly conflicts: ReadonlyArray<CmsContentPlanEntry>\n readonly unchanged: ReadonlyArray<CmsContentPlanEntry>\n readonly issues: ReadonlyArray<DocumentIssue>\n readonly targetOnly: ReadonlyArray<ContentSnapshotSource>\n readonly valid: boolean\n}\n\nexport interface CmsContentImportOptions {\n readonly overwrite?: boolean\n readonly publish?: boolean\n}\n\nexport interface CmsContentDiff {\n readonly changes: ReadonlyArray<{\n readonly filePath: string\n readonly local?: ContentSource\n readonly target?: ContentSource | ContentSnapshotSource\n readonly markdownChanged: boolean\n readonly publicationChanged: boolean\n }>\n readonly targetOnly: ReadonlyArray<ContentSource | ContentSnapshotSource>\n}\n\nexport interface CmsContentClient {\n readonly plan: (source: CmsContentSourceSet, options?: CmsContentImportOptions) => Promise<CmsContentPlan>\n readonly apply: (plan: CmsContentPlan) => Promise<ContentApplyResult>\n readonly diff: (source: CmsContentSourceSet) => Promise<CmsContentDiff>\n readonly export: (options: { readonly directory: string }) => Promise<CmsContentSourceSet>\n readonly readDocument: (documentId: string) => Promise<CmsContentDocument>\n}\n\ninterface PlanState {\n readonly client: object\n readonly input: {\n readonly sources: ReadonlyArray<ContentSource>\n readonly overwrite: boolean\n readonly publish: boolean\n }\n readonly protocol: ProtocolContentPlan\n}\n\ntype CmsContentRequestBody =\n | PlanState['input']\n | (PlanState['input'] & { readonly expectedGeneration: ProtocolContentPlan['generation'] })\n\nconst plans = new WeakMap<CmsContentPlan, PlanState>()\n\nexport function createCmsContentClient(options: CmsContentClientOptions): CmsContentClient {\n const baseUrl = contentBaseUrl(options.baseUrl)\n const requestFetch = options.fetch ?? globalThis.fetch\n const identity = {}\n let cookie: Promise<string> | undefined\n\n const authenticate = async (): Promise<string> => {\n if (cookie) return cookie\n\n cookie = request(requestFetch, new URL(`${CMS_AUTHENTICATION_PATH}/sign-in/email`, baseUrl), {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json', origin: baseUrl.origin },\n body: JSON.stringify(options.credentials),\n }).then(async (response) => {\n if (!response.ok) throw new CmsContentError('authentication-required', `CMS sign-in failed (${response.status}).`)\n const value = response.headers.get('set-cookie')?.split(';', 1)[0]\n\n if (!value) throw new CmsContentError('authentication-required', 'CMS sign-in did not return a session cookie.')\n\n return value\n })\n\n return cookie\n }\n\n const contentRequest = async <SchemaType extends Schema.ConstraintDecoder<unknown>>(\n path: string,\n schema: SchemaType,\n label: string,\n body?: CmsContentRequestBody,\n ): Promise<SchemaType['Type']> => {\n const session = await authenticate()\n\n const response = await request(requestFetch, new URL(`${STUDIO_API_PATH}/content/${path}`, baseUrl), {\n method: body === undefined ? 'GET' : 'POST',\n headers: {\n accept: 'application/json',\n cookie: session,\n ...(body === undefined ? undefined : { 'content-type': 'application/json' }),\n },\n ...(body === undefined ? undefined : { body: JSON.stringify(body) }),\n })\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403)\n throw new CmsContentError('authentication-required', `CMS content request was rejected (${response.status}).`)\n\n if (response.status === 409)\n throw new CmsContentError('generation-changed', 'The CMS changed after this content plan was created.')\n\n if (response.status === 422) {\n const failure = await decodeResponse(response, DocumentValidationFailed, 'document validation failure')\n\n throw new CmsContentError('invalid-document', 'The CMS rejected an invalid document.', {\n issues: failure.issues,\n })\n }\n\n throw new CmsContentError('network-error', `CMS content request failed (${response.status}).`)\n }\n\n return decodeResponse(response, schema, label)\n }\n\n const snapshot = async (): Promise<ContentSnapshot> =>\n contentRequest('snapshot', ContentSnapshotSchema, 'content snapshot')\n\n const client: CmsContentClient = {\n plan: async (source, authoredOptions = {}) => {\n const sources = Object.freeze(\n source.sources.map((entry) =>\n Object.freeze(\n ContentSourceSchema.make({\n filePath: entry.filePath,\n ...(entry.identity === undefined ? undefined : { identity: entry.identity }),\n markdown: entry.markdown,\n ...(entry.placement === undefined ? undefined : { placement: entry.placement }),\n published: entry.published,\n }),\n ),\n ),\n )\n\n const input = Object.freeze({\n sources,\n overwrite: authoredOptions.overwrite ?? false,\n publish: authoredOptions.publish ?? false,\n })\n\n const [protocol, current] = await Promise.all([\n contentRequest('plan', ProtocolContentPlanSchema, 'content plan', input),\n snapshot(),\n ])\n\n const documentIds = new Set(sources.flatMap((entry) => (entry.identity ? [entry.identity.documentId] : [])))\n\n const entries = (action: ContentPlanEntry['action']) =>\n protocol.entries.filter((entry) => entry.action === action)\n\n const plan: CmsContentPlan = Object.freeze({\n generation: protocol.generation,\n creates: entries('create'),\n updates: entries('update'),\n publications: entries('publish'),\n unpublications: entries('unpublish'),\n conflicts: entries('conflict'),\n unchanged: entries('unchanged'),\n issues: protocol.issues,\n targetOnly: current.sources.filter((entry) => !documentIds.has(entry.identity.documentId)),\n valid: protocol.valid,\n })\n\n plans.set(plan, { client: identity, input, protocol })\n\n return plan\n },\n apply: async (plan) => {\n const state = plans.get(plan)\n\n if (!state || state.client !== identity)\n throw new CmsContentError('content-conflict', 'This content plan was not created by this client.')\n\n if (!plan.valid)\n throw new CmsContentError('content-conflict', 'The content plan is not valid.', {\n conflicts: plan.conflicts,\n issues: plan.issues,\n })\n\n if (plan.conflicts.length)\n throw new CmsContentError('content-conflict', 'The content plan contains conflicts.', {\n conflicts: plan.conflicts,\n })\n\n if (plan.issues.length)\n throw new CmsContentError('invalid-document', 'The content plan contains invalid documents.', {\n issues: plan.issues,\n })\n\n return contentRequest('apply', ContentApplyResultSchema, 'content apply result', {\n ...state.input,\n expectedGeneration: state.protocol.generation,\n })\n },\n diff: async (source) => diffSources(source.sources, (await snapshot()).sources),\n export: async ({ directory }) => {\n const value = await snapshot()\n\n return writeContentDirectory(directory, value.sources)\n },\n readDocument: async (documentId) => {\n const document = (await snapshot()).sources.find((source) => source.identity.documentId === documentId)\n\n if (!document) throw new CmsContentError('document-not-found', `CMS document ${documentId} was not found.`)\n\n return document\n },\n }\n\n return client\n}\n\nexport async function readCmsContentDirectory(directory: string): Promise<CmsContentSourceSet> {\n try {\n const root = resolve(directory)\n const indexPath = await safeContentFile(root, '.cms-content.json')\n let index: ContentIndex | undefined\n\n try {\n index = parseIndex(await readFile(indexPath, 'utf8'))\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n\n if (index) {\n const sources = await Promise.all(\n index.sources.map(async (entry) =>\n decode(\n ContentSourceSchema,\n {\n filePath: entry.filePath,\n identity: entry.identity,\n markdown: await readFile(await safeContentFile(root, entry.filePath), 'utf8'),\n placement: entry.placement,\n published: entry.published,\n revisionId: entry.revisionId,\n },\n 'content source',\n ),\n ),\n )\n\n return { sources }\n }\n\n const files = await markdownFiles(root)\n\n if (!files.length) throw new CmsContentError('filesystem-error', `No Markdown files found in ${root}.`)\n\n return {\n sources: await Promise.all(\n files.map(async (file) =>\n decode(\n ContentSourceSchema,\n {\n filePath: relative(root, file).replaceAll('\\\\', '/'),\n markdown: await readFile(file, 'utf8'),\n published: true,\n },\n 'content source',\n ),\n ),\n ),\n }\n } catch (cause) {\n if (cause instanceof CmsContentError) throw cause\n throw new CmsContentError('filesystem-error', `Could not read CMS content from ${directory}.`, { cause })\n }\n}\n\nexport function diffCmsContentSources(\n local: ReadonlyArray<ContentSource>,\n target: ReadonlyArray<ContentSource | ContentSnapshotSource>,\n): CmsContentDiff {\n return diffSources(local, target)\n}\n\nconst ContentHash = Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/u))\n\nconst ContentIndexEntry = Schema.Struct({\n filePath: ContentSourceSchema.fields.filePath,\n identity: DocumentIdentity,\n placement: DocumentPlacement,\n published: Schema.Boolean,\n revisionId: ContentSnapshotSourceSchema.fields.revisionId,\n sha256: ContentHash,\n})\n\nconst ContentIndex = Schema.Struct({\n version: Schema.Literal(2),\n sources: Schema.Array(ContentIndexEntry),\n exportSha256: ContentHash,\n})\n\ntype ContentIndex = typeof ContentIndex.Type\n\ntype ContentIndexEntry = typeof ContentIndexEntry.Type\n\nasync function writeContentDirectory(\n directory: string,\n sources: ReadonlyArray<ContentSnapshotSource>,\n): Promise<CmsContentSourceSet> {\n try {\n const root = resolve(directory)\n const indexPath = await safeContentFile(root, '.cms-content.json')\n let previous: ContentIndex | undefined\n\n try {\n previous = parseIndex(await readFile(indexPath, 'utf8'))\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n\n const previousById = new Map(previous?.sources.map((entry) => [entry.identity.documentId, entry]))\n const paths = exportPaths(sources, previousById)\n\n if (previous) {\n const metadata = { version: previous.version, sources: previous.sources }\n\n if (sha256(JSON.stringify(metadata)) !== previous.exportSha256)\n throw new CmsContentError('filesystem-error', 'The local .cms-content.json file has been edited.')\n\n const incomingIds = new Set(sources.map((source) => source.identity.documentId))\n\n for (const entry of previous.sources)\n if (!incomingIds.has(entry.identity.documentId))\n throw new CmsContentError(\n 'filesystem-error',\n `CMS document ${entry.filePath} no longer exists; resolve the local file before exporting again.`,\n )\n }\n\n for (const source of sources) {\n const filePath = paths.get(source.identity.documentId)\n\n if (!filePath)\n throw new CmsContentError(\n 'filesystem-error',\n `Could not allocate an export path for ${source.identity.documentId}.`,\n )\n\n try {\n const local = await readFile(await safeContentFile(root, filePath), 'utf8')\n const before = previousById.get(source.identity.documentId)\n\n if (before ? sha256(local) !== before.sha256 : local !== source.markdown)\n throw new CmsContentError('filesystem-error', `Local edits in ${filePath}; export was stopped.`)\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n }\n\n await mkdir(root, { recursive: true })\n const entries: ContentIndexEntry[] = []\n\n for (const source of sources) {\n const filePath = paths.get(source.identity.documentId)\n\n if (!filePath)\n throw new CmsContentError(\n 'filesystem-error',\n `Could not allocate an export path for ${source.identity.documentId}.`,\n )\n const file = await safeContentFile(root, filePath)\n await mkdir(dirname(file), { recursive: true })\n await safeContentFile(root, filePath)\n await writeFile(file, source.markdown)\n entries.push({\n filePath,\n identity: source.identity,\n placement: source.placement,\n published: source.published,\n revisionId: source.revisionId,\n sha256: sha256(source.markdown),\n })\n }\n\n const metadata = { version: 2 as const, sources: entries }\n const index: ContentIndex = { ...metadata, exportSha256: sha256(JSON.stringify(metadata)) }\n await safeContentFile(root, '.cms-content.json')\n await writeFile(indexPath, `${JSON.stringify(index, undefined, 2)}\\n`)\n\n return {\n sources: sources.map((source) =>\n ContentSourceSchema.make({\n filePath: paths.get(source.identity.documentId)!,\n identity: source.identity,\n markdown: source.markdown,\n placement: source.placement,\n published: source.published,\n revisionId: source.revisionId,\n }),\n ),\n }\n } catch (cause) {\n throw new CmsContentError('filesystem-error', `Could not export CMS content to ${directory}.`, { cause })\n }\n}\n\nfunction diffSources(\n local: ReadonlyArray<ContentSource>,\n target: ReadonlyArray<ContentSource | ContentSnapshotSource>,\n): CmsContentDiff {\n const targetById = new Map(\n target.flatMap((source) => (source.identity ? [[source.identity.documentId, source] as const] : [])),\n )\n\n const targetByFile = new Map(\n target.flatMap((source) => ('filePath' in source ? [[source.filePath, source] as const] : [])),\n )\n\n const localIds = new Set(local.flatMap((source) => (source.identity ? [source.identity.documentId] : [])))\n const localFiles = new Set(local.map((source) => source.filePath))\n\n return {\n changes: local.flatMap((source) => {\n const current = source.identity ? targetById.get(source.identity.documentId) : targetByFile.get(source.filePath)\n const markdownChanged = current?.markdown !== source.markdown\n const publicationChanged = current !== undefined && current.published !== source.published\n\n return markdownChanged || publicationChanged\n ? [{ filePath: source.filePath, local: source, target: current, markdownChanged, publicationChanged }]\n : []\n }),\n targetOnly: target.filter((source) =>\n source.identity\n ? !localIds.has(source.identity.documentId)\n : 'filePath' in source && !localFiles.has(source.filePath),\n ),\n }\n}\n\nfunction exportPaths(\n sources: ReadonlyArray<ContentSnapshotSource>,\n previous: ReadonlyMap<string, ContentIndexEntry>,\n): ReadonlyMap<string, ContentFilePath> {\n const byId = new Map(sources.map((source) => [source.identity.documentId, source]))\n const allocated = new Set<string>()\n const result = new Map<string, ContentFilePath>()\n\n const segmentsFor = (source: ContentSnapshotSource, visited = new Set<string>()): ReadonlyArray<string> => {\n if (source.placement.kind === 'home') return []\n\n if (visited.has(source.identity.documentId)) return [source.placement.slug]\n const parent = byId.get(source.placement.parentDocumentId)\n\n return parent\n ? [...segmentsFor(parent, new Set([...visited, source.identity.documentId])), source.placement.slug]\n : [source.placement.slug]\n }\n\n for (const source of sources) {\n const retained = previous.get(source.identity.documentId)?.filePath\n const base = [source.identity.collection, ...(source.identity.locale ? [source.identity.locale] : [])]\n const placement = segmentsFor(source)\n\n const generated =\n source.placement.kind === 'home'\n ? [...base, 'index.md'].join('/')\n : [...base, ...placement.slice(0, -1), `${placement.at(-1) ?? 'document'}.md`].join('/')\n\n let candidate = retained ?? ContentFilePath.make(generated)\n\n if (allocated.has(candidate)) {\n candidate = ContentFilePath.make(generated.replace(/\\.md$/u, `-${source.identity.documentId.slice(0, 8)}.md`))\n }\n\n allocated.add(candidate)\n result.set(source.identity.documentId, candidate)\n }\n\n return result\n}\n\nasync function markdownFiles(directory: string): Promise<ReadonlyArray<string>> {\n const entries = await readdir(directory, { withFileTypes: true })\n\n const nested = await Promise.all(\n entries.map(async (entry) => {\n const path = resolve(directory, entry.name)\n\n if (entry.isDirectory()) return markdownFiles(path)\n\n return entry.isFile() && ['.md', '.mdc'].includes(extname(path)) ? [path] : []\n }),\n )\n\n return nested.flat().sort((left, right) => left.localeCompare(right))\n}\n\nfunction safeContentPath(root: string, filePath: string): string {\n const path = resolve(root, filePath)\n\n if (!path.startsWith(`${root}${sep}`))\n throw new CmsContentError('filesystem-error', `Unsafe content path: ${filePath}`)\n\n return path\n}\n\nasync function safeContentFile(root: string, filePath: string): Promise<string> {\n const path = safeContentPath(root, filePath)\n const segments = relative(root, path).split(sep)\n let current = root\n\n for (const segment of ['', ...segments]) {\n current = segment ? resolve(current, segment) : current\n\n try {\n if ((await lstat(current)).isSymbolicLink())\n throw new CmsContentError('filesystem-error', `Symlinks are not allowed in CMS content paths: ${filePath}`)\n } catch (cause) {\n if (!isMissingFile(cause)) throw cause\n }\n }\n\n return path\n}\n\nfunction contentBaseUrl(value: string): URL {\n let url: URL\n\n try {\n url = new URL(value)\n } catch (cause) {\n throw new CmsContentError('network-error', 'CMS baseUrl is invalid.', { cause })\n }\n\n if (url.username || url.password || url.search || url.hash)\n throw new CmsContentError('network-error', 'CMS baseUrl must be an origin without credentials, query, or fragment.')\n\n if (\n url.protocol !== 'https:' &&\n !(url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname))\n )\n throw new CmsContentError('network-error', 'Use HTTPS for CMS credentials; HTTP is allowed only on localhost.')\n\n return new URL(url.origin)\n}\n\nasync function request(fetch: typeof globalThis.fetch, input: URL, init: RequestInit): Promise<Response> {\n try {\n return await fetch(input, init)\n } catch (cause) {\n throw new CmsContentError('network-error', `Could not reach ${input.origin}.`, { cause })\n }\n}\n\nasync function decodeResponse<SchemaType extends Schema.ConstraintDecoder<unknown>>(\n response: Response,\n schema: SchemaType,\n label: string,\n): Promise<SchemaType['Type']> {\n try {\n return decode(schema, await response.json(), label)\n } catch (cause) {\n if (cause instanceof CmsContentError) throw cause\n throw new CmsContentError('invalid-response', 'CMS returned an invalid JSON response.', { cause })\n }\n}\n\n/* oxlint-disable anti-slop/no-unknown-parameters -- Untrusted JSON and filesystem values enter their explicit Schema decoder here. */\nfunction decode<SchemaType extends Schema.ConstraintDecoder<unknown>>(\n schema: SchemaType,\n value: unknown,\n label: string,\n): SchemaType['Type'] {\n const decoded = Schema.decodeUnknownResult(schema)(value)\n\n if (Result.isFailure(decoded))\n throw new CmsContentError('invalid-response', `CMS returned an invalid ${label}.`, { cause: decoded.failure })\n\n return decoded.success\n}\n/* oxlint-enable anti-slop/no-unknown-parameters */\n\nfunction sha256(value: string): string {\n return Encoding.encodeHex(\n Effect.runSync(NodeCrypto.make.digest('SHA-256', new TextEncoder().encode(value)).pipe(Effect.orDie)),\n )\n}\n\nfunction parseIndex(value: string): ContentIndex {\n const decoded = Schema.decodeUnknownResult(ContentIndex)(JSON.parse(value))\n\n if (Result.isFailure(decoded))\n throw new CmsContentError('filesystem-error', 'The .cms-content.json index is invalid.')\n\n const filePaths = new Set(decoded.success.sources.map((entry) => entry.filePath))\n\n if (filePaths.size !== decoded.success.sources.length)\n throw new CmsContentError('filesystem-error', 'The .cms-content.json index contains duplicate file paths.')\n\n return decoded.success\n}\n\nfunction isMissingFile(cause: unknown): boolean {\n return cause instanceof Error && 'code' in cause && cause.code === 'ENOENT'\n}\n\nexport type { ContentApplyResult, ContentSource }\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { o as PublicPath, r as DocumentId } from "./scalars-CVZqT3L0.js";
|
|
|
2
2
|
import { P as DocumentSeo, _ as DocumentSourceMapping, b as DocumentValidationResult, l as DocumentIssue, n as CmsMarkdownDocument, r as CompiledDocument, t as CmsDocumentAnalysis } from "./models-VmGmG19-.js";
|
|
3
3
|
import { i as decodeManagedMediaReference, r as decodeAuthoredDocumentReference } from "./References-CCPDAPve.js";
|
|
4
4
|
import { c as resolveCmsComarkAttributes, d as createCmsComarkRenderData, l as withCmsComarkProps, o as normalizeCmsComponentBindings, u as cmsComarkTextContent } from "./Forms-CX-hwmJF.js";
|
|
5
|
-
import { h as SOURCE_MAPPINGS_META_KEY, l as validateCollectionBody, m as createDocumentParser, o as createAuthoringDocumentValidator, p as DOCUMENT_ENGINE_FINGERPRINT } from "./Configuration-
|
|
5
|
+
import { h as SOURCE_MAPPINGS_META_KEY, l as validateCollectionBody, m as createDocumentParser, o as createAuthoringDocumentValidator, p as DOCUMENT_ENGINE_FINGERPRINT } from "./Configuration-CMweD9bn.js";
|
|
6
6
|
import { DateTime, Effect, Option, Predicate, Result, Schema } from "effect";
|
|
7
7
|
|
|
8
8
|
//#region ../document/src/internal/document-address.ts
|
|
@@ -47,7 +47,7 @@ function resolveDocumentAddress(address, relativeKey, data) {
|
|
|
47
47
|
return normalizePublicPath(resolved);
|
|
48
48
|
}
|
|
49
49
|
function localizeDocumentPath(key, locale, configuration) {
|
|
50
|
-
if (!configuration || !locale || locale === configuration.defaultLocale &&
|
|
50
|
+
if (!configuration || !locale || locale === configuration.defaultLocale && configuration.prefix !== "always") return key;
|
|
51
51
|
return PublicPath.make(`/${locale}${key === "/" ? "" : key}`);
|
|
52
52
|
}
|
|
53
53
|
function normalizePublicPath(value) {
|
|
@@ -446,7 +446,7 @@ function createCatalogLookup(documents, configuration) {
|
|
|
446
446
|
if (direct) return Option.some(direct);
|
|
447
447
|
const locales = configuration.documents.locales;
|
|
448
448
|
if (!locales) return Option.none();
|
|
449
|
-
const request = localizedRequest(path, locales.locales, locales.defaultLocale, locales.
|
|
449
|
+
const request = localizedRequest(path, locales.locales, locales.defaultLocale, locales.prefix);
|
|
450
450
|
if (!request) return Option.none();
|
|
451
451
|
const localized = byVariant.get(localeAndKey(request.locale, request.key));
|
|
452
452
|
if (localized) return Option.some(localized);
|
|
@@ -462,10 +462,10 @@ function createCatalogLookup(documents, configuration) {
|
|
|
462
462
|
function localeAndKey(locale, key) {
|
|
463
463
|
return `${locale ?? ""}:${key}`;
|
|
464
464
|
}
|
|
465
|
-
function localizedRequest(path, locales, defaultLocale,
|
|
465
|
+
function localizedRequest(path, locales, defaultLocale, prefix) {
|
|
466
466
|
const segments = path === "/" ? [] : path.slice(1).split("/");
|
|
467
467
|
const possibleLocale = locales.find((locale) => locale === segments[0]);
|
|
468
|
-
const prefixedLocale = possibleLocale && (possibleLocale !== defaultLocale ||
|
|
468
|
+
const prefixedLocale = possibleLocale && (possibleLocale !== defaultLocale || prefix === "always") ? possibleLocale : void 0;
|
|
469
469
|
if (prefixedLocale) {
|
|
470
470
|
const keyResult = normalizePublicPath(segments.slice(1).join("/"));
|
|
471
471
|
return Result.isSuccess(keyResult) ? {
|
|
@@ -473,7 +473,7 @@ function localizedRequest(path, locales, defaultLocale, prefixDefaultLocale) {
|
|
|
473
473
|
locale: prefixedLocale
|
|
474
474
|
} : void 0;
|
|
475
475
|
}
|
|
476
|
-
if (
|
|
476
|
+
if (prefix === "always") return void 0;
|
|
477
477
|
return {
|
|
478
478
|
key: path,
|
|
479
479
|
locale: defaultLocale
|
|
@@ -975,4 +975,4 @@ function errorMessage(cause) {
|
|
|
975
975
|
|
|
976
976
|
//#endregion
|
|
977
977
|
export { DocumentCompilationFailed as n, createDocumentEngine as t };
|
|
978
|
-
//# sourceMappingURL=DocumentEngine-
|
|
978
|
+
//# sourceMappingURL=DocumentEngine-tYtwbBjr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentEngine-tYtwbBjr.js","names":["nestedValue","PublicPathSchema","CmsDocumentAnalysisSchema","visit","isDocumentParseFailed","DocumentSourceMappingSchema","EffectResult","CompiledDocumentSchema","EffectOption","invalid","PublicPathSchema","DocumentParseFailedError","DocumentValidationResultSchema"],"sources":["../../../../document/src/internal/document-address.ts","../../../../document/src/internal/document-engine/errors.ts","../../../../document/src/internal/comark/analysis.ts","../../../../document/src/internal/document-engine/frontmatter-validation.ts","../../../../document/src/internal/document-engine/compilation.ts","../../../../document/src/internal/document-engine/catalog-lookup.ts","../../../../document/src/internal/document-engine/catalog-issues.ts","../../../../document/src/internal/document-engine/reference-target.ts","../../../../document/src/internal/document-engine/references.ts","../../../../document/src/internal/document-engine/catalog.ts","../../../../document/src/internal/document-engine/configuration.ts","../../../../document/src/DocumentEngine.ts"],"sourcesContent":["import type { RoutePattern, Locale, LocaleConfiguration } from '@internal/protocol/Configuration'\nimport { Predicate, Result, Schema } from 'effect'\nimport { PublicPath as PublicPathSchema, type PublicPath } from '@internal/protocol/Documents'\n\nexport interface DocumentAddressToken {\n readonly catchAll: boolean\n readonly name: string\n}\n\nexport interface DocumentAddress {\n readonly pattern: RoutePattern\n readonly tokens: ReadonlyArray<DocumentAddressToken>\n}\n\nexport interface DocumentAddressError {\n readonly field?: string\n readonly message: string\n}\n\nconst addressTokenPattern = /:([a-z][\\w.]*)(\\*)?/giu\n\nexport function parseDocumentAddress(pattern: RoutePattern): Result.Result<DocumentAddress, DocumentAddressError> {\n const matches = [...pattern.matchAll(addressTokenPattern)]\n\n const tokens = matches.map((match) => ({\n catchAll: match[2] === '*',\n name: match[1] ?? '',\n }))\n\n const remainder = pattern.replace(addressTokenPattern, '')\n\n if (remainder.includes(':') || tokens.some((token) => !token.name)) {\n return Result.fail({\n field: 'routes.entry',\n message: `Document address pattern \"${pattern}\" contains an invalid token.`,\n })\n }\n\n if (tokens.filter((token) => token.catchAll).length > 1) {\n return Result.fail({\n field: 'routes.entry',\n message: `Document address pattern \"${pattern}\" contains more than one catch-all token.`,\n })\n }\n\n if (new Set(tokens.map((token) => token.name)).size !== tokens.length) {\n return Result.fail({\n field: 'routes.entry',\n message: `Document address pattern \"${pattern}\" contains duplicate tokens.`,\n })\n }\n\n return Result.succeed({ pattern, tokens })\n}\n\nexport function resolveDocumentAddress(\n address: DocumentAddress,\n relativeKey: PublicPath,\n data: Schema.JsonObject,\n): Result.Result<PublicPath, DocumentAddressError> {\n const relativePath = relativeKey === '/' ? '' : relativeKey.slice(1)\n let resolved: string = address.pattern\n\n for (const token of address.tokens) {\n const authored = nestedValue(data, token.name)\n const fallback = token.catchAll ? relativePath : undefined\n\n const value =\n authored === undefined ? fallback : Predicate.isString(authored) && authored.trim() ? authored : undefined\n\n if (value === undefined) {\n return Result.fail({\n field: token.name,\n message:\n authored === undefined\n ? `Document address field \"${token.name}\" is required by pattern \"${address.pattern}\".`\n : `Document address field \"${token.name}\" must be a non-empty string.`,\n })\n }\n\n const normalized = token.catchAll ? normalizeDocumentRelativePath(value) : normalizeDocumentSegment(value)\n\n if (Result.isFailure(normalized)) return Result.fail(normalized.failure)\n resolved = resolved.replace(`:${token.name}${token.catchAll ? '*' : ''}`, normalized.success)\n }\n\n return normalizePublicPath(resolved)\n}\n\nexport function localizeDocumentPath(\n key: PublicPath,\n locale: Locale | undefined,\n configuration: LocaleConfiguration | undefined,\n): PublicPath {\n if (!configuration || !locale || (locale === configuration.defaultLocale && configuration.prefix !== 'always')) {\n return key\n }\n\n return PublicPathSchema.make(`/${locale}${key === '/' ? '' : key}`)\n}\n\nexport function normalizePublicPath(value: string): Result.Result<PublicPath, DocumentAddressError> {\n const path = `/${value.replace(/\\\\/gu, '/').replace(/^\\/+|\\/+$/gu, '')}`.replace(/\\/{2,}/gu, '/')\n\n return Schema.decodeResult(PublicPathSchema)(path).pipe(\n Result.mapError(() => ({\n field: 'path',\n message: `Document path \"${value}\" cannot be normalized into a public path.`,\n })),\n )\n}\n\nexport function normalizeDocumentRelativePath(value: string): Result.Result<string, DocumentAddressError> {\n if (!value.trim()) return Result.succeed('')\n\n const segments = value.replace(/\\\\/gu, '/').split('/').filter(Boolean)\n const normalized: string[] = []\n\n for (const segment of segments) {\n const result = normalizeDocumentSegment(segment)\n\n if (Result.isFailure(result)) return result\n normalized.push(result.success)\n }\n\n return Result.succeed(normalized.join('/'))\n}\n\nexport function normalizeDocumentSegment(value: string): Result.Result<string, DocumentAddressError> {\n const normalized = value\n .trim()\n .normalize('NFKC')\n .toLocaleLowerCase()\n .replace(/[^\\p{Letter}\\p{Number}_-]+/gu, '-')\n .replace(/^-+|-+$/gu, '')\n\n return normalized\n ? Result.succeed(normalized)\n : Result.fail({ message: `Document path segment \"${value}\" is empty after normalization.` })\n}\n\nfunction nestedValue(value: Schema.JsonObject, path: string): Schema.Json | undefined {\n return path.split('.').reduce<Schema.Json | undefined>((current, segment) => {\n if (!Schema.is(Schema.JsonObject)(current)) return undefined\n\n return current[segment]\n }, value)\n}\n","import { DocumentIssue } from '@internal/protocol/Documents'\nimport { DocumentId } from '@internal/protocol/Documents'\nimport { Schema } from 'effect'\n\nexport class DocumentEngineConfigurationInvalid extends Schema.TaggedError<DocumentEngineConfigurationInvalid>()(\n 'DocumentEngine.ConfigurationInvalid',\n {\n message: Schema.NonEmptyString,\n field: Schema.optionalKey(Schema.NonEmptyString),\n },\n) {}\n\nexport class DocumentParseFailed extends Schema.TaggedError<DocumentParseFailed>()(\n 'DocumentEngine.DocumentParseFailed',\n {\n documentId: DocumentId,\n cause: Schema.Defect(),\n },\n) {}\n\nexport class DocumentCompilationFailed extends Schema.TaggedError<DocumentCompilationFailed>()(\n 'DocumentEngine.DocumentCompilationFailed',\n {\n issues: Schema.Array(DocumentIssue),\n },\n) {}\n","import type { CmsDocumentAnalysis, CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport { CmsDocumentAnalysis as CmsDocumentAnalysisSchema } from '@internal/protocol/Documents'\nimport { Predicate } from 'effect'\nimport { cmsComarkTextContent } from './document-adapter'\n\nexport const CMS_STANDARD_TAGS = new Set([\n 'a',\n 'abbr',\n 'address',\n 'article',\n 'aside',\n 'b',\n 'blockquote',\n 'br',\n 'button',\n 'caption',\n 'code',\n 'col',\n 'colgroup',\n 'dd',\n 'del',\n 'details',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'figcaption',\n 'figure',\n 'footer',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'i',\n 'img',\n 'kbd',\n 'li',\n 'main',\n 'mark',\n 'nav',\n 'ol',\n 'p',\n 'pre',\n 'q',\n 's',\n 'section',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n])\n\nexport function analyzeCmsDocument(\n body: CmsMarkdownDocument,\n metadata: { readonly description?: string; readonly title: string },\n): CmsDocumentAnalysis {\n const headings: Array<{ readonly depth: number; readonly id: string; readonly text: string }> = []\n const components = new Set<string>()\n\n visit(body.nodes, (node) => {\n const tag = node[0].toLocaleLowerCase()\n\n if (/^h[1-6]$/u.test(tag)) {\n headings.push({\n depth: Number(tag.slice(1)),\n id: Predicate.isString(node[1].id) ? node[1].id : '',\n text: cmsComarkTextContent(node).trim(),\n })\n } else if (!CMS_STANDARD_TAGS.has(tag)) {\n components.add(tag)\n }\n })\n\n const bodyText = normalizeText(body.nodes.map(cmsComarkTextContent).join(' '))\n const summary = normalizeText(metadata.description ?? firstParagraph(body.nodes) ?? metadata.title)\n const searchText = normalizeText([metadata.title, metadata.description, bodyText].filter(Boolean).join(' '))\n\n return CmsDocumentAnalysisSchema.make({\n components: [...components].sort(),\n headings,\n searchText,\n summary,\n })\n}\n\nfunction visit(\n nodes: ReadonlyArray<MarkdownNode>,\n inspect: (node: Exclude<MarkdownNode, string | readonly [null, object, string]>) => void,\n): void {\n for (const node of nodes) {\n if (Predicate.isString(node) || node[0] === null) continue\n inspect(node)\n const [, , ...children] = node\n visit(children, inspect)\n }\n}\n\nfunction firstParagraph(nodes: ReadonlyArray<MarkdownNode>): string | undefined {\n const paragraph = nodes.find((node) => Array.isArray(node) && node[0] === 'p')\n\n if (!paragraph || Predicate.isString(paragraph) || paragraph[0] === null) return undefined\n const text = normalizeText(cmsComarkTextContent(paragraph))\n\n return text || undefined\n}\n\nfunction normalizeText(value: string): string {\n return value.replace(/\\s+/gu, ' ').trim()\n}\n","import type { CollectionDefinition } from '@internal/protocol/Configuration'\nimport type { DocumentIssue } from '@internal/protocol/Documents'\nimport type { DocumentId } from '@internal/protocol/Documents'\nimport type { DocumentSchemaIssue, ExecutableDocumentSchema } from './document-schema'\nimport { Effect, Option, Predicate, Schema } from 'effect'\n\nexport const validateFrontmatter = Effect.fn('DocumentEngine.validateFrontmatter')(function* (\n raw: Schema.JsonObject,\n schema: ExecutableDocumentSchema,\n type: CollectionDefinition,\n documentId: DocumentId,\n) {\n const projection = schema.project(raw)\n\n const issues = projection.unknownPaths\n .toSorted()\n .map((path): DocumentIssue => unknownFieldIssue(path, type, documentId))\n\n const result = yield* schema.validate(projection.value)\n\n if ('issues' in result) {\n issues.push(...result.issues.map((issue) => schemaIssue(issue, projection.value, type, documentId)))\n\n return { data: projection.value, issues }\n }\n\n const parsed = Schema.decodeUnknownOption(Schema.JsonObject)(result.value)\n\n if (Option.isNone(parsed)) {\n issues.push(\n issue(\n 'schema.constraint',\n 'The collection schema output must be a JSON-compatible object.',\n type,\n documentId,\n 'frontmatter',\n ),\n )\n\n return { data: projection.value, issues }\n }\n\n return issues.length === 0 ? { data: parsed.value, issues } : { data: projection.value, issues }\n})\n\nfunction unknownFieldIssue(path: string, type: CollectionDefinition, documentId: DocumentId): DocumentIssue {\n if (path === 'id') {\n return issue(\n 'document.id',\n 'Document identity is managed by the CMS and cannot be authored in frontmatter.',\n type,\n documentId,\n path,\n )\n }\n\n return issue(\n 'schema.unknown',\n `Frontmatter field \"${path}\" is not declared by collection \"${type.collection}\".`,\n type,\n documentId,\n path,\n )\n}\n\nfunction schemaIssue(\n error: DocumentSchemaIssue,\n input: Schema.JsonObject,\n type: CollectionDefinition,\n documentId: DocumentId,\n): DocumentIssue {\n const field = issuePath(error.path)\n const code = issueCode(error, input, field)\n\n return issue(code, error.message, type, documentId, field || undefined)\n}\n\nfunction issueCode(error: DocumentSchemaIssue, input: Schema.JsonObject, field: string): DocumentIssue['code'] {\n if (error.code === 'invalid_type') return nestedValue(input, field) === undefined ? 'schema.required' : 'schema.type'\n\n if (error.code === 'invalid_value') return 'schema.option'\n\n return 'schema.constraint'\n}\n\nfunction issuePath(path: DocumentSchemaIssue['path']): string {\n return (path ?? [])\n .map((segment) => (Predicate.hasProperty(segment, 'key') ? segment.key : segment))\n .map(String)\n .join('.')\n}\n\nfunction nestedValue(value: Schema.JsonObject, path: string): Schema.Json | undefined {\n if (!path) return value\n\n return path.split('.').reduce<Schema.Json | undefined>((current, segment) => {\n if (Array.isArray(current)) {\n const index = Number(segment)\n\n return Number.isSafeInteger(index) ? current[index] : undefined\n }\n\n return Schema.is(Schema.JsonObject)(current) ? current[segment] : undefined\n }, value)\n}\n\nfunction issue(\n code: DocumentIssue['code'],\n message: string,\n type: CollectionDefinition,\n documentId: DocumentId,\n field?: string,\n): DocumentIssue {\n return {\n code,\n collection: type.collection,\n ...(field === undefined ? undefined : { field }),\n message,\n severity: 'error',\n documentId,\n }\n}\n","import type {\n DocumentIssue,\n DocumentSourceMapping,\n CmsMarkdownDocument as MarkdownDocumentType,\n} from '@internal/protocol/Documents'\nimport type { DocumentSeo as DocumentSeoType } from '@internal/protocol/Seo'\nimport type { ComarkParseFn } from 'comark'\nimport type { DocumentCompilationSource } from './compilation-source'\nimport type { ResolvedDocumentEngineConfiguration, ResolvedCollection } from './configuration'\nimport {\n CompiledDocument,\n DocumentSourceMapping as DocumentSourceMappingSchema,\n CmsMarkdownDocument,\n PublicPath,\n} from '@internal/protocol/Documents'\nimport { localizeDocumentPath, resolveDocumentAddress } from '../document-address'\nimport { DocumentSeo } from '@internal/protocol/Seo'\nimport { Effect, Predicate, Result, Schema } from 'effect'\nimport { DocumentCompilationFailed, DocumentParseFailed } from './errors'\nimport { normalizeCmsComponentBindings } from '../comark/bindings'\nimport { analyzeCmsDocument } from '../comark/analysis'\nimport { DOCUMENT_ENGINE_FINGERPRINT } from '../comark/grammar'\nimport { validateFrontmatter } from './frontmatter-validation'\nimport { SOURCE_MAPPINGS_META_KEY } from '../comark/source-mapping'\n\nconst isDocumentParseFailed = Schema.is(DocumentParseFailed)\n\nexport const compileCompiledDocument = Effect.fn('DocumentEngine.compileDocument')(function* (\n configuration: ResolvedDocumentEngineConfiguration,\n parseMarkdown: ComarkParseFn,\n source: DocumentCompilationSource,\n) {\n const collection = yield* resolveCollection(configuration, source)\n const parsedBody = yield* parseBody(parseMarkdown, source)\n const mappings = yield* sourceMappings(parsedBody, source)\n const body = normalizeCmsComponentBindings(withoutSourceMappings(parsedBody), configuration.components)\n const { collectionFrontmatter, rawSeo } = splitFrontmatter(body.frontmatter)\n const seoProjection = projectSeo(rawSeo, source.identity.documentId)\n\n const validation = yield* validateFrontmatter(\n collectionFrontmatter,\n collection.schema,\n collection.definition,\n source.identity.documentId,\n ).pipe(\n Effect.mapError(\n (cause) =>\n new DocumentCompilationFailed({\n issues: [\n {\n code: 'schema.constraint',\n collection: collection.definition.collection,\n documentId: source.identity.documentId,\n message: cause.message,\n severity: 'error',\n },\n ],\n }),\n ),\n )\n\n const relativeKey = PublicPath.make(source.placement.kind === 'home' ? '/' : `/${source.placement.slug}`)\n const route = source.placement.kind === 'home' ? collection.homeRoute : collection.entryRoute\n const address = resolveDocumentAddress(route, relativeKey, validation.data)\n const key = Result.isSuccess(address) ? address.success : provisionalKey(source.identity.documentId)\n const path = localizeDocumentPath(key, source.identity.locale, configuration.documents.locales)\n\n const title =\n stringValue(validation.data.title) ??\n stringValue(body.meta.title) ??\n (source.placement.kind === 'home' ? collection.definition.label : humanize(source.placement.slug))\n\n const description = stringValue(validation.data.description) ?? stringValue(body.meta.description)\n\n const issues = Result.isSuccess(address)\n ? validation.issues\n : [...validation.issues, addressIssue(address.failure, source.identity.documentId)]\n\n const canonicalFrontmatter = rawSeo === undefined ? validation.data : Object.assign({ _seo: rawSeo }, validation.data)\n\n const canonicalBody = CmsMarkdownDocument.make({\n frontmatter: canonicalFrontmatter,\n meta: body.meta,\n nodes: body.nodes,\n })\n\n const analysis = analyzeCmsDocument(canonicalBody, description === undefined ? { title } : { description, title })\n\n return CompiledDocument.make(\n Object.assign(\n {\n id: source.identity.documentId,\n identity: source.identity,\n placement: source.placement,\n key,\n path,\n collection: source.identity.collection,\n draft: source.draft,\n title,\n data: validation.data,\n issues: [\n ...issues,\n ...seoProjection.issues,\n ...(configuration.validateAuthoringDocument?.(canonicalBody, collection.definition.body) ?? []).map(\n (issue): DocumentIssue => ({\n code: 'reference.component',\n component: issue.component,\n documentId: source.identity.documentId,\n ...(issue.field ? { field: issue.field.join('.') } : undefined),\n message: issue.message,\n severity: 'error',\n }),\n ),\n ],\n analysis,\n body: canonicalBody,\n engineFingerprint: DOCUMENT_ENGINE_FINGERPRINT,\n source: {\n mappings,\n ...(source.publishedAt === undefined ? undefined : { publishedAt: source.publishedAt }),\n },\n },\n source.identity.locale === undefined ? undefined : { locale: source.identity.locale },\n description === undefined ? undefined : { description },\n seoProjection.seo === undefined ? undefined : { seo: seoProjection.seo },\n ),\n )\n})\n\ninterface FrontmatterProjection {\n readonly collectionFrontmatter: Schema.JsonObject\n readonly rawSeo: Schema.Json | undefined\n}\n\nfunction splitFrontmatter(frontmatter: Schema.JsonObject): FrontmatterProjection {\n const { _seo: rawSeo, ...collectionFrontmatter } = frontmatter\n\n return { collectionFrontmatter, rawSeo }\n}\n\ninterface SeoProjection {\n readonly seo?: DocumentSeoType\n readonly issues: ReadonlyArray<DocumentIssue>\n}\n\nfunction projectSeo(\n rawSeo: Schema.Json | undefined,\n documentId: DocumentCompilationSource['identity']['documentId'],\n): SeoProjection {\n if (rawSeo === undefined) return { issues: [] }\n const decoded = Schema.decodeUnknownResult(DocumentSeo)(rawSeo, { onExcessProperty: 'error' })\n\n if (Result.isSuccess(decoded)) return { issues: [], seo: decoded.success }\n\n return {\n issues: [\n {\n code: 'seo.invalid',\n documentId,\n field: '_seo',\n message: `Document SEO is invalid: ${String(decoded.failure)}`,\n severity: 'error',\n },\n ],\n }\n}\n\nfunction provisionalKey(documentId: DocumentCompilationSource['identity']['documentId']): PublicPath {\n return PublicPath.make(`/_cms-invalid/${documentId}`)\n}\n\nfunction addressIssue(\n error: { readonly field?: string; readonly message: string },\n documentId: DocumentCompilationSource['identity']['documentId'],\n): DocumentIssue {\n return {\n code: 'document.invalid',\n documentId,\n ...(error.field === undefined ? undefined : { field: error.field }),\n message: error.message,\n severity: 'error',\n }\n}\n\nfunction resolveCollection(\n configuration: ResolvedDocumentEngineConfiguration,\n source: DocumentCompilationSource,\n): Effect.Effect<ResolvedCollection, DocumentCompilationFailed> {\n const collection = configuration.types.find(({ definition }) => definition.collection === source.identity.collection)\n\n if (!collection) {\n return compilationFailure({\n code: 'document.invalid',\n documentId: source.identity.documentId,\n field: 'identity.collection',\n message: `Document collection \"${source.identity.collection}\" does not exist.`,\n severity: 'error',\n })\n }\n\n const locales = configuration.documents.locales\n const locale = source.identity.locale\n\n if ((!locales && locale !== undefined) || (locales && (locale === undefined || !locales.locales.includes(locale)))) {\n return compilationFailure({\n code: 'document.invalid',\n documentId: source.identity.documentId,\n field: 'identity.locale',\n message: locale ? `Document locale \"${locale}\" is not configured.` : 'A locale is required for this document.',\n severity: 'error',\n })\n }\n\n return Effect.succeed(collection)\n}\n\nfunction parseBody(\n parseMarkdown: ComarkParseFn,\n source: DocumentCompilationSource,\n): Effect.Effect<MarkdownDocumentType, DocumentParseFailed> {\n return Effect.tryPromise({\n try: () => parseMarkdown(source.markdown),\n catch: (cause) => new DocumentParseFailed({ cause, documentId: source.identity.documentId }),\n }).pipe(\n Effect.flatMap(Schema.decodeUnknownEffect(CmsMarkdownDocument)),\n Effect.mapError((cause) =>\n isDocumentParseFailed(cause) ? cause : new DocumentParseFailed({ cause, documentId: source.identity.documentId }),\n ),\n )\n}\n\nfunction sourceMappings(\n body: MarkdownDocumentType,\n source: DocumentCompilationSource,\n): Effect.Effect<ReadonlyArray<DocumentSourceMapping>, DocumentParseFailed> {\n return Schema.decodeUnknownEffect(Schema.Array(DocumentSourceMappingSchema))(\n body.meta[SOURCE_MAPPINGS_META_KEY] ?? [],\n ).pipe(Effect.mapError((cause) => new DocumentParseFailed({ cause, documentId: source.identity.documentId })))\n}\n\nfunction withoutSourceMappings(body: MarkdownDocumentType): MarkdownDocumentType {\n const { [SOURCE_MAPPINGS_META_KEY]: _mappings, ...meta } = body.meta\n\n return CmsMarkdownDocument.make({ frontmatter: body.frontmatter, meta, nodes: body.nodes })\n}\n\nfunction compilationFailure(issue: DocumentIssue): Effect.Effect<never, DocumentCompilationFailed> {\n return Effect.fail(new DocumentCompilationFailed({ issues: [issue] }))\n}\n\nfunction stringValue(value: Schema.Json | undefined): string | undefined {\n return Predicate.isString(value) && value.trim() ? value.trim() : undefined\n}\n\nfunction humanize(value: string): string {\n return value.replace(/[-_]+/gu, ' ').replace(/^./u, (character) => character.toLocaleUpperCase())\n}\n","import type { Locale } from '@internal/protocol/Configuration'\nimport type { CompiledDocument, DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport type { ResolvedDocumentEngineConfiguration } from './configuration'\nimport { normalizePublicPath } from '../document-address'\nimport { Option, Result } from 'effect'\n\nexport interface CatalogLookup {\n readonly findById: (documentId: DocumentId) => Option.Option<CompiledDocument>\n readonly findByKey: (key: string, locale?: Locale) => Option.Option<CompiledDocument>\n readonly findByPath: (path: string) => Option.Option<CompiledDocument>\n}\n\nexport function createCatalogLookup(\n documents: ReadonlyArray<CompiledDocument>,\n configuration: ResolvedDocumentEngineConfiguration,\n): CatalogLookup {\n const byPath = new Map(documents.map((document) => [document.path, document]))\n const byId = new Map(documents.map((document) => [document.id, document]))\n const byVariant = new Map(documents.map((document) => [localeAndKey(document.locale, document.key), document]))\n\n const findByKey = (input: string, locale?: Locale) => {\n const keyResult = normalizePublicPath(input)\n\n if (Result.isFailure(keyResult)) return Option.none<CompiledDocument>()\n const key = keyResult.success\n const locales = configuration.documents.locales\n\n if (!locales) return Option.fromNullishOr(byVariant.get(localeAndKey(undefined, key)))\n const requestedLocale = locale ?? locales.defaultLocale\n const localized = byVariant.get(localeAndKey(requestedLocale, key))\n\n if (localized) return Option.some(localized)\n\n if (!locales.fallbackLocale) return Option.none()\n\n return Option.fromNullishOr(byVariant.get(localeAndKey(locales.fallbackLocale, key)))\n }\n\n const findByPath = (input: string) => {\n const pathResult = normalizePublicPath(input)\n\n if (Result.isFailure(pathResult)) return Option.none<CompiledDocument>()\n const path = pathResult.success\n const direct = byPath.get(path)\n\n if (direct) return Option.some(direct)\n\n const locales = configuration.documents.locales\n\n if (!locales) return Option.none()\n const request = localizedRequest(path, locales.locales, locales.defaultLocale, locales.prefix)\n\n if (!request) return Option.none()\n const localized = byVariant.get(localeAndKey(request.locale, request.key))\n\n if (localized) return Option.some(localized)\n\n if (!locales.fallbackLocale) return Option.none()\n\n return Option.fromNullishOr(byVariant.get(localeAndKey(locales.fallbackLocale, request.key)))\n }\n\n return {\n findById: (documentId) => Option.fromNullishOr(byId.get(documentId)),\n findByKey,\n findByPath,\n }\n}\n\nexport function localeAndKey(locale: Locale | undefined, key: PublicPath): string {\n return `${locale ?? ''}:${key}`\n}\n\nfunction localizedRequest(\n path: PublicPath,\n locales: ReadonlyArray<Locale>,\n defaultLocale: Locale,\n prefix: 'always' | null,\n): { readonly key: PublicPath; readonly locale: Locale } | undefined {\n const segments = path === '/' ? [] : path.slice(1).split('/')\n const possibleLocale = locales.find((locale) => locale === segments[0])\n\n const prefixedLocale =\n possibleLocale && (possibleLocale !== defaultLocale || prefix === 'always') ? possibleLocale : undefined\n\n if (prefixedLocale) {\n const keyResult = normalizePublicPath(segments.slice(1).join('/'))\n\n return Result.isSuccess(keyResult) ? { key: keyResult.success, locale: prefixedLocale } : undefined\n }\n\n if (prefix === 'always') return undefined\n\n return { key: path, locale: defaultLocale }\n}\n","import type { CompiledDocument, DocumentIssue, PublicPath } from '@internal/protocol/Documents'\nimport type { ResolvedDocumentEngineConfiguration } from './configuration'\nimport { localeAndKey } from './catalog-lookup'\n\nexport function collisionIssues(documents: ReadonlyArray<CompiledDocument>): DocumentIssue[] {\n const issues: DocumentIssue[] = []\n const byId = new Map<string, CompiledDocument>()\n const byPath = new Map<string, CompiledDocument>()\n const byVariant = new Map<string, CompiledDocument>()\n\n for (const document of documents) {\n const identityCollision = byId.get(document.id)\n\n if (identityCollision) {\n issues.push(collisionIssue(`Document identity collision for \"${document.id}\".`, document))\n } else byId.set(document.id, document)\n\n const pathCollision = byPath.get(document.path)\n\n if (pathCollision) {\n issues.push(\n collisionIssue(\n `Document route collision at \"${document.path}\" between documents \"${pathCollision.id}\" and \"${document.id}\".`,\n document,\n document.path,\n ),\n )\n } else byPath.set(document.path, document)\n\n const variant = localeAndKey(document.locale, document.key)\n const variantCollision = byVariant.get(variant)\n\n if (variantCollision && variantCollision.path !== pathCollision?.path) {\n issues.push(\n collisionIssue(\n `Document locale collision at \"${document.key}\" between documents \"${variantCollision.id}\" and \"${document.id}\".`,\n document,\n document.key,\n ),\n )\n } else byVariant.set(variant, document)\n }\n\n return issues\n}\n\nexport function translationIssues(\n documents: ReadonlyArray<CompiledDocument>,\n configuration: ResolvedDocumentEngineConfiguration,\n): DocumentIssue[] {\n const locales = configuration.documents.locales\n\n if (!locales) return []\n const variants = new Set(documents.map((document) => localeAndKey(document.locale, document.key)))\n const keys = new Set(documents.map((document) => document.key))\n\n return [...keys].flatMap((key) =>\n locales.locales.flatMap((locale): DocumentIssue[] =>\n variants.has(localeAndKey(locale, key))\n ? []\n : [\n {\n code: 'i18n.missing-translation',\n key,\n locale,\n message: `Document \"${key}\" is missing its \"${locale}\" translation.`,\n severity: 'warning',\n },\n ],\n ),\n )\n}\n\nfunction collisionIssue(message: string, document: CompiledDocument, key?: PublicPath): DocumentIssue {\n const issue = {\n code: 'document.collision' as const,\n message,\n severity: 'error' as const,\n documentId: document.id,\n }\n\n return key === undefined ? issue : Object.assign(issue, { key })\n}\n","import type { DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport type { MediaId } from '@internal/protocol/Media'\nimport type { CmsComarkAttributeValue, CmsComarkAttributes } from '../comark/bindings'\nimport { decodeAuthoredDocumentReference, decodeManagedMediaReference } from '@internal/protocol/References'\nimport { Predicate } from 'effect'\nimport { CMS_STANDARD_TAGS } from '../comark/analysis'\n\nexport type DocumentReferenceTarget =\n | { readonly kind: 'component'; readonly name: string }\n | { readonly kind: 'document'; readonly documentId: DocumentId; readonly lastKnownRoute: PublicPath }\n | { readonly kind: 'media'; readonly key: string; readonly mediaId?: MediaId }\n\nexport function referenceTarget(\n tag: string,\n attributes: CmsComarkAttributes,\n mediaBaseUrl: string | undefined,\n): DocumentReferenceTarget | undefined {\n if (tag === 'a') return decodeDocumentReference(attributes.get('href'))\n\n if (tag === 'img') {\n const key = mediaKey(attributes.get('src'), mediaBaseUrl)\n\n return key ? { kind: 'media', key } : undefined\n }\n\n const normalizedTag = tag.toLocaleLowerCase()\n\n return CMS_STANDARD_TAGS.has(normalizedTag) ? undefined : { kind: 'component', name: normalizedTag }\n}\n\nexport function targetKey(target: DocumentReferenceTarget): string {\n switch (target.kind) {\n case 'component':\n return `component:${target.name.toLocaleLowerCase()}`\n case 'document':\n return `document:${target.documentId}`\n case 'media':\n return `media:${target.key}`\n }\n}\n\nexport function decodeDocumentReference(value: CmsComarkAttributeValue): DocumentReferenceTarget | undefined {\n if (!Predicate.isString(value)) return undefined\n const reference = decodeAuthoredDocumentReference(value)\n\n return reference ? { kind: 'document', ...reference } : undefined\n}\n\nexport function decodeMediaReference(\n value: CmsComarkAttributeValue,\n mediaBaseUrl: string | undefined,\n): DocumentReferenceTarget | undefined {\n if (!Predicate.isString(value)) return undefined\n const reference = decodeManagedMediaReference(value)\n\n if (!reference) return undefined\n const key = mediaKey(reference.lastKnownUrl, mediaBaseUrl)\n\n return key ? { kind: 'media', key, mediaId: reference.mediaId } : undefined\n}\n\nfunction mediaKey(value: CmsComarkAttributeValue, mediaBaseUrl: string | undefined): string | undefined {\n if (!Predicate.isString(value) || mediaBaseUrl === undefined) return undefined\n const prefix = `${mediaBaseUrl}/`\n\n if (!value.startsWith(prefix)) return undefined\n const encodedKey = value.slice(prefix.length).split(/[?#]/u, 1)[0]\n\n if (!encodedKey) return undefined\n\n try {\n const segments = encodedKey.split('/').map(decodeURIComponent)\n\n if (\n segments.some(\n (segment) =>\n !segment ||\n segment === '.' ||\n segment === '..' ||\n segment.includes('/') ||\n segment.includes('\\\\') ||\n hasControlCharacter(segment),\n )\n ) {\n return undefined\n }\n\n const key = segments.join('/')\n\n return key.startsWith('media/') ? key : undefined\n } catch {\n return undefined\n }\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const codePoint = character.codePointAt(0)\n\n if (codePoint !== undefined && (codePoint <= 31 || codePoint === 127)) return true\n }\n\n return false\n}\n","import type { StructuredField } from '@internal/protocol/StructuredFields'\nimport type { CompiledDocument, DocumentId, DocumentIssue, MarkdownNode } from '@internal/protocol/Documents'\nimport type { PublicPath } from '@internal/protocol/Documents'\nimport type { CmsComarkAttributes } from '../comark/bindings'\nimport type { NodeRenderData } from 'comark'\nimport type { ResolvedDocumentEngineConfiguration } from './configuration'\nimport type { DocumentReferenceTarget } from './reference-target'\nimport { decodeManagedMediaReference } from '@internal/protocol/References'\nimport { Option, Predicate, Schema } from 'effect'\nimport { resolveCmsComarkAttributes, withCmsComarkProps } from '../comark/bindings'\nimport { createCmsComarkRenderData } from '../comark/document-adapter'\nimport { decodeDocumentReference, decodeMediaReference, referenceTarget, targetKey } from './reference-target'\n\nexport type { DocumentReferenceTarget } from './reference-target'\n\nexport interface DocumentReference {\n readonly nodePath: ReadonlyArray<number>\n readonly source: {\n readonly documentId: DocumentId\n readonly route: PublicPath\n }\n readonly target: DocumentReferenceTarget\n}\n\nexport interface DocumentReferenceIndex {\n readonly all: ReadonlyArray<DocumentReference>\n readonly impact: (target: DocumentReferenceTarget) => ReadonlyArray<DocumentReference>\n}\n\ninterface IndexedDocumentReferences {\n readonly index: DocumentReferenceIndex\n readonly issues: ReadonlyMap<DocumentId, ReadonlyArray<DocumentIssue>>\n}\n\nconst noReferences: ReadonlyArray<DocumentReference> = Object.freeze([])\n\nexport function createDocumentReferenceIndex(\n documents: ReadonlyArray<CompiledDocument>,\n configuration: ResolvedDocumentEngineConfiguration,\n findById: (documentId: DocumentId) => Option.Option<CompiledDocument>,\n): IndexedDocumentReferences {\n const all: DocumentReference[] = []\n const byTarget = new Map<string, DocumentReference[]>()\n const issues = new Map<DocumentId, DocumentIssue[]>()\n\n for (const document of documents) {\n const invalidManagedMedia = (lastKnownUrl: string): void =>\n addIssue(issues, document.id, {\n code: 'reference.media',\n documentId: document.id,\n message: `Managed-media reference \"${lastKnownUrl}\" is outside the configured media library.`,\n severity: 'error',\n })\n\n const indexTarget = (target: DocumentReferenceTarget | undefined, nodePath: ReadonlyArray<number>): void => {\n if (!target) return\n\n const reference = freezeReference({\n nodePath,\n source: {\n documentId: document.id,\n route: document.path,\n },\n target,\n })\n\n all.push(reference)\n const key = targetKey(target)\n const matching = byTarget.get(key) ?? []\n matching.push(reference)\n byTarget.set(key, matching)\n\n if (target.kind === 'document' && Option.isNone(findById(target.documentId))) {\n addIssue(issues, document.id, {\n code: 'reference.document',\n documentId: document.id,\n key: target.lastKnownRoute,\n message: `Document link target \"${target.documentId}\" does not resolve.`,\n severity: 'error',\n })\n }\n }\n\n const seoImageTarget = document.seo?.socialImage\n ? referenceTarget('img', new Map([['src', document.seo.socialImage.url]]), configuration.mediaBaseUrl)\n : undefined\n\n indexTarget(\n seoImageTarget?.kind === 'media'\n ? Object.assign({}, seoImageTarget, { mediaId: document.seo?.socialImage?.mediaId })\n : seoImageTarget,\n [],\n )\n\n const collection = configuration.types.find(({ definition }) => definition.collection === document.collection)\n\n for (const target of propertyTargets(\n collection?.definition.authoringFields ?? [],\n document.data,\n configuration.mediaBaseUrl,\n invalidManagedMedia,\n ))\n indexTarget(target, [])\n\n visit(document.body.nodes, createCmsComarkRenderData(document.body), (tag, attributes, children, nodePath) => {\n const targets = [\n referenceTarget(tag, attributes, configuration.mediaBaseUrl),\n ...propertyTargets(\n configuration.components?.get(tag.toLowerCase())?.authoring.props ?? [],\n Object.fromEntries([...attributes].flatMap(([key, value]) => (value === undefined ? [] : [[key, value]]))),\n configuration.mediaBaseUrl,\n invalidManagedMedia,\n ),\n ]\n\n for (const target of targets) indexTarget(target, nodePath)\n })\n }\n\n const frozenAll = Object.freeze(all)\n const frozenByTarget = new Map([...byTarget].map(([key, references]) => [key, Object.freeze(references)] as const))\n\n return {\n index: Object.freeze({\n all: frozenAll,\n impact: (target: DocumentReferenceTarget) => frozenByTarget.get(targetKey(target)) ?? noReferences,\n }),\n issues,\n }\n}\n\nfunction visit(\n nodes: CompiledDocument['body']['nodes'],\n renderData: NodeRenderData,\n onElement: (\n tag: string,\n attributes: CmsComarkAttributes,\n children: ReadonlyArray<MarkdownNode>,\n nodePath: ReadonlyArray<number>,\n ) => void,\n parentPath: ReadonlyArray<number> = [],\n): void {\n nodes.forEach((node, index) => {\n if (Predicate.isString(node) || node[0] === null) return\n const [tag, attributes, ...children] = node\n const nodePath = [...parentPath, index]\n const resolved = resolveCmsComarkAttributes(attributes, renderData)\n onElement(tag, resolved, children, nodePath)\n const childrenRenderData = withCmsComarkProps(renderData, resolved)\n visit(children, childrenRenderData, onElement, nodePath)\n })\n}\n\nfunction freezeReference(reference: DocumentReference): DocumentReference {\n return Object.freeze({\n nodePath: Object.freeze([...reference.nodePath]),\n source: Object.freeze({ ...reference.source }),\n target: Object.freeze({ ...reference.target }),\n })\n}\n\nfunction addIssue(issues: Map<DocumentId, DocumentIssue[]>, documentId: DocumentId, issue: DocumentIssue): void {\n const sourceIssues = issues.get(documentId) ?? []\n sourceIssues.push(issue)\n issues.set(documentId, sourceIssues)\n}\n\nfunction propertyTargets(\n fields: ReadonlyArray<StructuredField>,\n values: Schema.JsonObject,\n mediaBaseUrl: string | undefined,\n onInvalidManagedMedia: (lastKnownUrl: string) => void,\n): DocumentReferenceTarget[] {\n return fields.flatMap((field) => {\n const value = values[field.name] === undefined ? field.defaultValue : values[field.name]\n\n if (field.input === 'document') {\n const target = decodeDocumentReference(value)\n\n return target ? [target] : []\n }\n\n if (field.input === 'media') {\n const target = decodeMediaReference(value, mediaBaseUrl)\n\n if (!target && Predicate.isString(value)) {\n const reference = decodeManagedMediaReference(value)\n\n if (reference) onInvalidManagedMedia(reference.lastKnownUrl)\n }\n\n return target ? [target] : []\n }\n\n if (field.input === 'link' || field.input === 'image') {\n const target = referenceTarget(\n field.input === 'link' ? 'a' : 'img',\n new Map([[field.input === 'link' ? 'href' : 'src', value]]),\n mediaBaseUrl,\n )\n\n return target ? [target] : []\n }\n\n if (field.fields)\n return (Array.isArray(value) ? value : [value]).flatMap((entry) =>\n Schema.is(Schema.JsonObject)(entry)\n ? propertyTargets(field.fields ?? [], entry, mediaBaseUrl, onInvalidManagedMedia)\n : [],\n )\n\n return []\n })\n}\n","import type { Locale } from '@internal/protocol/Configuration'\nimport type { CompiledDocument, DocumentId, DocumentIssue, MarkdownNode } from '@internal/protocol/Documents'\nimport type { Option, Result } from 'effect'\nimport type { ResolvedDocumentEngineConfiguration } from './configuration'\nimport type { DocumentReferenceIndex } from './references'\nimport {\n CompiledDocument as CompiledDocumentSchema,\n PublicPath as PublicPathSchema,\n} from '@internal/protocol/Documents'\nimport { Option as EffectOption, Result as EffectResult, Schema } from 'effect'\nimport { collisionIssues, translationIssues } from './catalog-issues'\nimport { createCatalogLookup } from './catalog-lookup'\nimport { DocumentCompilationFailed } from './errors'\nimport { createDocumentReferenceIndex } from './references'\nimport { decodeDocumentReference } from './reference-target'\nimport { decodeManagedMediaReference } from '@internal/protocol/References'\nimport { localizeDocumentPath, resolveDocumentAddress } from '../document-address'\n\nexport interface DocumentCatalog {\n readonly documents: ReadonlyArray<CompiledDocument>\n readonly issues: ReadonlyArray<DocumentIssue>\n readonly findById: (documentId: DocumentId) => Option.Option<CompiledDocument>\n readonly findByKey: (key: string, locale?: Locale) => Option.Option<CompiledDocument>\n readonly findByPath: (path: string) => Option.Option<CompiledDocument>\n readonly references: DocumentReferenceIndex\n}\n\nexport function createDocumentCatalog(\n configuration: ResolvedDocumentEngineConfiguration,\n input: ReadonlyArray<CompiledDocument>,\n): Result.Result<DocumentCatalog, DocumentCompilationFailed> {\n const resolved = resolvePlacementGraph(configuration, input)\n\n if (EffectResult.isFailure(resolved)) return EffectResult.fail(resolved.failure)\n const documents = resolved.success.toSorted((left, right) => left.path.localeCompare(right.path))\n const collisions = collisionIssues(documents)\n\n if (collisions.length > 0) return EffectResult.fail(new DocumentCompilationFailed({ issues: collisions }))\n\n const lookup = createCatalogLookup(documents, configuration)\n const references = createDocumentReferenceIndex(documents, configuration, lookup.findById)\n\n const withReferenceIssues = documents.map((document) => {\n const additional = references.issues.get(document.id) ?? []\n const projected = resolveSemanticRoutes(document, lookup.findById)\n\n return additional.length === 0\n ? projected\n : CompiledDocumentSchema.make(Object.assign({}, projected, { issues: [...document.issues, ...additional] }))\n })\n\n const finalLookup = createCatalogLookup(withReferenceIssues, configuration)\n\n return EffectResult.succeed({\n documents: withReferenceIssues,\n issues: [\n ...withReferenceIssues.flatMap((document) => document.issues),\n ...translationIssues(withReferenceIssues, configuration),\n ],\n ...finalLookup,\n references: references.index,\n } satisfies DocumentCatalog)\n}\n\nfunction resolveSemanticRoutes(document: CompiledDocument, findById: DocumentCatalog['findById']): CompiledDocument {\n const nodes = document.body.nodes.map((node) => resolveNodeReferences(node, findById))\n const data = resolveJsonObjectReferences(document.data, findById)\n const frontmatter = resolveJsonObjectReferences(document.body.frontmatter, findById)\n\n return CompiledDocumentSchema.make(\n Object.assign({}, document, {\n data,\n body: Object.assign({}, document.body, { frontmatter, nodes }),\n }),\n )\n}\n\nfunction resolveNodeReferences(node: MarkdownNode, findById: DocumentCatalog['findById']): MarkdownNode {\n if (Schema.is(Schema.String)(node)) return node\n const [tag, attributes, ...children] = node\n\n if (tag === null) return node\n\n return [\n tag,\n resolveJsonObjectReferences(attributes, findById),\n ...children.map((child) => resolveNodeReferences(child, findById)),\n ]\n}\n\nfunction resolveJsonObjectReferences(\n value: Schema.JsonObject,\n findById: DocumentCatalog['findById'],\n): Schema.JsonObject {\n return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolveJsonReferences(entry, findById)]))\n}\n\nfunction resolveJsonReferences(value: Schema.Json, findById: DocumentCatalog['findById']): Schema.Json {\n if (Schema.is(Schema.String)(value)) {\n const reference = decodeDocumentReference(value)\n\n if (reference?.kind === 'document') {\n const target = findById(reference.documentId)\n\n return EffectOption.isSome(target) ? target.value.path : reference.lastKnownRoute\n }\n\n return decodeManagedMediaReference(value)?.lastKnownUrl ?? value\n }\n\n if (Array.isArray(value)) return value.map((entry) => resolveJsonReferences(entry, findById))\n\n if (Schema.is(Schema.JsonObject)(value)) {\n return resolveJsonObjectReferences(value, findById)\n }\n\n return value\n}\n\nfunction resolvePlacementGraph(\n configuration: ResolvedDocumentEngineConfiguration,\n documents: ReadonlyArray<CompiledDocument>,\n): Result.Result<ReadonlyArray<CompiledDocument>, DocumentCompilationFailed> {\n const byId = new Map<DocumentId, CompiledDocument>()\n const homes = new Map<string, CompiledDocument>()\n const issues: DocumentIssue[] = []\n\n for (const document of documents) {\n const duplicate = byId.get(document.id)\n\n if (duplicate) {\n issues.push(invalid(document, `Document identity \"${document.id}\" appears more than once.`))\n continue\n }\n\n byId.set(document.id, document)\n\n if (document.placement.kind === 'home') {\n const key = identityScope(document)\n const existing = homes.get(key)\n\n if (existing) {\n issues.push(\n invalid(\n document,\n `Documents \"${existing.id}\" and \"${document.id}\" are both home documents for collection \"${document.collection}\"${document.locale ? ` in locale \"${document.locale}\"` : ''}.`,\n ),\n )\n } else homes.set(key, document)\n }\n }\n\n const segments = new Map<DocumentId, ReadonlyArray<string>>()\n const visiting = new Set<DocumentId>()\n\n const resolveSegments = (document: CompiledDocument): ReadonlyArray<string> | undefined => {\n const cached = segments.get(document.id)\n\n if (cached) return cached\n\n if (visiting.has(document.id)) {\n issues.push(invalid(document, `Document placement cycle includes \"${document.id}\".`, 'placement'))\n\n return undefined\n }\n\n visiting.add(document.id)\n let result: ReadonlyArray<string> | undefined\n\n if (document.placement.kind === 'home') result = []\n else {\n const parent = byId.get(document.placement.parentDocumentId)\n\n if (!parent) {\n issues.push(\n invalid(\n document,\n `Parent document \"${document.placement.parentDocumentId}\" does not exist in this catalog.`,\n 'placement.parentDocumentId',\n ),\n )\n } else if (parent.collection !== document.collection) {\n issues.push(\n invalid(document, 'A parent document must belong to the same collection.', 'placement.parentDocumentId'),\n )\n } else if (parent.locale !== document.locale) {\n issues.push(invalid(document, 'A parent document must use the same locale.', 'placement.parentDocumentId'))\n } else {\n const collection = configuration.types.find(({ definition }) => definition.collection === document.collection)\n\n if (!collection) issues.push(invalid(document, `Collection \"${document.collection}\" is not configured.`))\n else if (!collection.definition.hierarchy && parent.placement.kind !== 'home') {\n issues.push(\n invalid(document, 'This collection allows entries only directly below its home document.', 'placement'),\n )\n } else {\n const parentSegments = resolveSegments(parent)\n\n if (parentSegments) result = [...parentSegments, document.placement.slug]\n }\n }\n }\n\n visiting.delete(document.id)\n\n if (result) segments.set(document.id, result)\n\n return result\n }\n\n for (const document of documents) resolveSegments(document)\n\n if (issues.length > 0) return EffectResult.fail(new DocumentCompilationFailed({ issues }))\n\n const projected = documents.map((document) => {\n const collection = configuration.types.find(({ definition }) => definition.collection === document.collection)\n const placementSegments = segments.get(document.id)\n\n if (!collection || !placementSegments) return document\n const relativeKey = PublicPathSchema.make(`/${placementSegments.join('/')}`)\n const configuredRoute = document.placement.kind === 'home' ? collection.homeRoute : collection.entryRoute\n const route = resolveDocumentAddress(configuredRoute, relativeKey, document.data)\n\n if (EffectResult.isFailure(route)) {\n issues.push(invalid(document, route.failure.message, route.failure.field))\n\n return document\n }\n\n return CompiledDocumentSchema.make(\n Object.assign({}, document, {\n key: route.success,\n path: localizeDocumentPath(route.success, document.locale, configuration.documents.locales),\n }),\n )\n })\n\n return issues.length > 0\n ? EffectResult.fail(new DocumentCompilationFailed({ issues }))\n : EffectResult.succeed(projected)\n}\n\nfunction identityScope(document: CompiledDocument): string {\n return `${document.collection}:${document.locale ?? ''}`\n}\n\nfunction invalid(document: CompiledDocument, message: string, field?: string): DocumentIssue {\n return {\n code: 'document.invalid',\n collection: document.collection,\n documentId: document.id,\n ...(field === undefined ? undefined : { field }),\n ...(document.locale === undefined ? undefined : { locale: document.locale }),\n message,\n severity: 'error',\n }\n}\n","import type { ComponentDefinition, DocumentConfiguration, CollectionDefinition } from '@internal/protocol/Configuration'\nimport type { DocumentAddress } from '../document-address'\nimport type { ExecutableDocumentModel, ExecutableDocumentSchema } from './document-schema'\nimport { parseDocumentAddress } from '../document-address'\nimport { createAuthoringDocumentValidator, validateCollectionBody } from '../../AuthoringSchema'\nimport { Result } from 'effect'\nimport { DocumentEngineConfigurationInvalid } from './errors'\n\nexport interface ResolvedCollection {\n readonly definition: CollectionDefinition\n readonly entryRoute: DocumentAddress\n readonly homeRoute: DocumentAddress\n readonly schema: ExecutableDocumentSchema\n}\n\nexport interface ResolvedDocumentEngineConfiguration {\n readonly components?: ReadonlyMap<string, ComponentDefinition>\n readonly validateAuthoringDocument?: ReturnType<typeof createAuthoringDocumentValidator>\n readonly documents: DocumentConfiguration\n readonly mediaBaseUrl?: string\n readonly types: ReadonlyArray<ResolvedCollection>\n}\n\nexport interface DocumentEngineOptions {\n readonly components?: ReadonlyArray<ComponentDefinition>\n readonly documentModel: ExecutableDocumentModel\n readonly mediaBaseUrl?: string\n}\n\ntype ResolvedDocumentEngineConfigurationBuilder = {\n -readonly [Key in keyof ResolvedDocumentEngineConfiguration]: ResolvedDocumentEngineConfiguration[Key]\n}\n\nexport function resolveDocumentEngineConfiguration(\n documents: DocumentConfiguration,\n options: DocumentEngineOptions,\n): Result.Result<ResolvedDocumentEngineConfiguration, DocumentEngineConfigurationInvalid> {\n if (documents.types.length === 0) return invalid('Documents must define at least one collection.', 'types')\n\n const collections = new Set<string>()\n const resolved: ResolvedCollection[] = []\n\n for (const definition of documents.types) {\n if (collections.has(definition.collection)) {\n return invalid(`Document collection \"${definition.collection}\" is defined more than once.`, 'types')\n }\n\n collections.add(definition.collection)\n\n const homeRoute = parseDocumentAddress(definition.routes.home)\n const entryRoute = parseDocumentAddress(definition.routes.entry)\n\n if (Result.isFailure(homeRoute)) return invalid(homeRoute.failure.message, homeRoute.failure.field)\n\n if (Result.isFailure(entryRoute)) return invalid(entryRoute.failure.message, entryRoute.failure.field)\n\n if (homeRoute.success.tokens.length > 0) {\n return invalid(`Document collection \"${definition.collection}\" home route cannot contain tokens.`, 'types')\n }\n\n if (definition.hierarchy && !entryRoute.success.tokens.some((token) => token.catchAll)) {\n return invalid(\n `Document collection \"${definition.collection}\" can only enable hierarchy with a catch-all entry route.`,\n 'types',\n )\n }\n\n const schema = options.documentModel.types[definition.collection]\n\n if (!schema)\n return invalid(`Document collection \"${definition.collection}\" has no executable schema.`, 'documentModel')\n\n resolved.push({ definition, entryRoute: entryRoute.success, homeRoute: homeRoute.success, schema })\n }\n\n const locales = documents.locales\n\n if (locales) {\n if (new Set(locales.locales).size !== locales.locales.length)\n return invalid('Document locales must be unique.', 'locales.locales')\n\n if (!locales.locales.includes(locales.defaultLocale)) {\n return invalid(`Default locale \"${locales.defaultLocale}\" is not configured.`, 'locales.defaultLocale')\n }\n\n if (locales.fallbackLocale && !locales.locales.includes(locales.fallbackLocale)) {\n return invalid(`Fallback locale \"${locales.fallbackLocale}\" is not configured.`, 'locales.fallbackLocale')\n }\n }\n\n let components: ReadonlyMap<string, ComponentDefinition> | undefined\n let validateAuthoringDocument: ReturnType<typeof createAuthoringDocumentValidator> | undefined\n\n if (options.components !== undefined) {\n const result = resolveComponents(options.components)\n\n if (Result.isFailure(result)) return Result.fail(result.failure)\n components = result.success.components\n validateAuthoringDocument = result.success.validateAuthoringDocument\n\n for (const definition of documents.types) {\n const issues = validateCollectionBody(options.components, definition.body)\n\n if (issues.length) return invalid(`${definition.label}: ${issues.join(' ')}`, 'body')\n }\n }\n\n const mediaBaseUrl = options.mediaBaseUrl?.replace(/\\/+$/u, '')\n\n const configuration: ResolvedDocumentEngineConfigurationBuilder = {\n documents,\n types: resolved,\n }\n\n if (components !== undefined) configuration.components = components\n\n if (validateAuthoringDocument !== undefined) configuration.validateAuthoringDocument = validateAuthoringDocument\n\n if (mediaBaseUrl !== undefined) configuration.mediaBaseUrl = mediaBaseUrl\n\n return Result.succeed(configuration satisfies ResolvedDocumentEngineConfiguration)\n}\n\nfunction resolveComponents(definitions: ReadonlyArray<ComponentDefinition>): Result.Result<\n {\n readonly components: ReadonlyMap<string, ComponentDefinition>\n readonly validateAuthoringDocument: ReturnType<typeof createAuthoringDocumentValidator>\n },\n DocumentEngineConfigurationInvalid\n> {\n const components = new Map<string, ComponentDefinition>()\n\n for (const component of definitions) {\n const name = component.name.toLocaleLowerCase()\n\n if (components.has(name))\n return invalid(`Document component \"${component.name}\" is defined more than once.`, 'components')\n components.set(name, component)\n }\n\n try {\n return Result.succeed({ components, validateAuthoringDocument: createAuthoringDocumentValidator(components) })\n } catch (cause) {\n return invalid(cause instanceof Error ? cause.message : 'The component authoring catalog is invalid.', 'components')\n }\n}\n\nfunction invalid(message: string, field?: string): Result.Result<never, DocumentEngineConfigurationInvalid> {\n return Result.fail(new DocumentEngineConfigurationInvalid(field === undefined ? { message } : { field, message }))\n}\n","import type { DocumentConfiguration } from '@internal/protocol/Configuration'\nimport type { CompiledDocument, DocumentIssue, DocumentValidationResult } from '@internal/protocol/Documents'\nimport type { DocumentCompilationSource } from './internal/document-engine/compilation-source'\nimport type { DocumentEngineOptions } from './internal/document-engine/configuration'\nimport type { DocumentCompilationFailed, DocumentParseFailed } from './internal/document-engine/errors'\nimport type { DocumentCatalog } from './internal/document-engine/catalog'\nimport { DocumentValidationResult as DocumentValidationResultSchema } from '@internal/protocol/Documents'\nimport { DateTime, Effect, Result, Schema } from 'effect'\nimport { compileCompiledDocument } from './internal/document-engine/compilation'\nimport { DOCUMENT_ENGINE_FINGERPRINT, createDocumentParser } from './internal/comark/grammar'\nimport { createDocumentCatalog } from './internal/document-engine/catalog'\nimport { resolveDocumentEngineConfiguration } from './internal/document-engine/configuration'\nimport { DocumentParseFailed as DocumentParseFailedError } from './internal/document-engine/errors'\n\ntype CompilationError = DocumentCompilationFailed | DocumentParseFailed\n\nexport interface DocumentCatalogCompilation {\n readonly previous?: DocumentCatalog\n readonly sources: ReadonlyArray<DocumentCompilationSource>\n}\n\nconst isDocumentParseFailed = Schema.is(DocumentParseFailedError)\n\n/**\n * Portable authority for compiled Documents. `compileAll` reuses unchanged\n * source compilations from `previous`, then rebuilds the catalog-wide collision,\n * translation, and reference projection. `validate` reports every parse or\n * compilation failure as data and therefore has no error channel.\n */\nexport interface DocumentEngine {\n readonly fingerprint: string\n readonly compile: (source: DocumentCompilationSource) => Effect.Effect<CompiledDocument, CompilationError>\n readonly compileAll: (input: DocumentCatalogCompilation) => Effect.Effect<DocumentCatalog, CompilationError>\n readonly validate: (source: DocumentCompilationSource) => Effect.Effect<DocumentValidationResult>\n}\n\nexport const createDocumentEngine = Effect.fn('DocumentEngine.make')(function* (\n documents: DocumentConfiguration,\n options: DocumentEngineOptions,\n) {\n const configuration = yield* Effect.fromResult(resolveDocumentEngineConfiguration(documents, options))\n const parseMarkdown = createDocumentParser()\n\n const compilations = new WeakMap<\n DocumentCatalog,\n ReadonlyMap<string, { readonly document: CompiledDocument; readonly source: DocumentCompilationSource }>\n >()\n\n const compile = Effect.fn('DocumentEngine.compile')((source: DocumentCompilationSource) =>\n compileCompiledDocument(configuration, parseMarkdown, source),\n )\n\n const compileAll = Effect.fn('DocumentEngine.compileAll')(function* (input: DocumentCatalogCompilation) {\n const previous = input.previous ? compilations.get(input.previous) : undefined\n\n const compiled = yield* Effect.forEach(input.sources, (source) => {\n const cached = previous?.get(source.identity.documentId)\n\n return cached && sameCompilationSource(cached.source, source) ? Effect.succeed(cached.document) : compile(source)\n })\n\n const catalog = yield* Effect.fromResult(createDocumentCatalog(configuration, compiled))\n compilations.set(\n catalog,\n new Map(\n input.sources.map((source, index) => {\n const document = compiled[index]\n\n if (!document) throw new Error(`Compiled document \"${source.identity.documentId}\" is missing.`)\n\n return [source.identity.documentId, { document, source }] as const\n }),\n ),\n )\n\n return catalog\n })\n\n const validate = Effect.fn('DocumentEngine.validate')(function* (source: DocumentCompilationSource) {\n const result = yield* Effect.result(compile(source))\n\n if (Result.isSuccess(result)) {\n const document = result.success\n\n return DocumentValidationResultSchema.make({\n valid: !document.issues.some((issue) => issue.severity === 'error'),\n document,\n issues: document.issues,\n })\n }\n\n const error = result.failure\n\n const issues: ReadonlyArray<DocumentIssue> = isDocumentParseFailed(error)\n ? [\n {\n code: 'markdown.parse',\n message: errorMessage(error.cause),\n severity: 'error',\n documentId: error.documentId,\n },\n ]\n : error.issues\n\n return DocumentValidationResultSchema.make({\n valid: false,\n issues,\n })\n })\n\n return {\n compile,\n compileAll,\n fingerprint: DOCUMENT_ENGINE_FINGERPRINT,\n validate,\n } satisfies DocumentEngine\n})\n\nfunction sameCompilationSource(left: DocumentCompilationSource, right: DocumentCompilationSource): boolean {\n return (\n left.identity.documentId === right.identity.documentId &&\n left.identity.collection === right.identity.collection &&\n left.identity.locale === right.identity.locale &&\n left.placement.kind === right.placement.kind &&\n (left.placement.kind === 'home' ||\n (right.placement.kind === 'entry' &&\n left.placement.parentDocumentId === right.placement.parentDocumentId &&\n left.placement.slug === right.placement.slug)) &&\n left.draft === right.draft &&\n left.markdown === right.markdown &&\n samePublishedAt(left.publishedAt, right.publishedAt)\n )\n}\n\nfunction samePublishedAt(\n left: DocumentCompilationSource['publishedAt'],\n right: DocumentCompilationSource['publishedAt'],\n): boolean {\n return left === undefined || right === undefined ? left === right : DateTime.Equivalence(left, right)\n}\n\nfunction errorMessage(cause: unknown): string {\n return cause instanceof Error && cause.message ? cause.message : 'Markdown could not be parsed.'\n}\n\nexport { DocumentCompilationSource } from './internal/document-engine/compilation-source'\n\nexport type { DocumentCatalog } from './internal/document-engine/catalog'\n\nexport type { DocumentEngineOptions } from './internal/document-engine/configuration'\n\nexport {\n DocumentCompilationFailed,\n DocumentEngineConfigurationInvalid,\n DocumentParseFailed,\n} from './internal/document-engine/errors'\n\nexport type {\n DocumentReference,\n DocumentReferenceIndex,\n DocumentReferenceTarget,\n} from './internal/document-engine/references'\n\nexport { encodeAuthoredDocumentReference as encodeDocumentReference } from '@internal/protocol/References'\n\nexport type {\n DocumentSchemaIssue,\n DocumentSchemaProjection,\n DocumentSchemaValidation,\n ExecutableDocumentModel,\n ExecutableDocumentSchema,\n} from './internal/document-engine/document-schema'\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
//#region ../protocol/src/HttpPaths.ts
|
|
2
2
|
const STUDIO_BASE_PATH = "/_cms";
|
|
3
|
-
const STUDIO_APP_PATH = `${STUDIO_BASE_PATH}/app`;
|
|
4
3
|
const STUDIO_API_PATH = `${STUDIO_BASE_PATH}/api`;
|
|
5
4
|
const STUDIO_COLLABORATION_PATH = `${STUDIO_BASE_PATH}/collaboration`;
|
|
6
5
|
const STUDIO_HEALTH_PATH = `${STUDIO_BASE_PATH}/health`;
|
|
@@ -17,5 +16,5 @@ const CMS_PREVIEW_SEO_PATH = `${STUDIO_API_PATH}/preview/seo`;
|
|
|
17
16
|
const CMS_FORM_SUBMIT_PATH = `${STUDIO_API_PATH}/forms/submit`;
|
|
18
17
|
|
|
19
18
|
//#endregion
|
|
20
|
-
export { CMS_FORM_SUBMIT_PATH as a, CMS_PREVIEW_READ_PATH as c,
|
|
21
|
-
//# sourceMappingURL=HttpPaths-
|
|
19
|
+
export { CMS_FORM_SUBMIT_PATH as a, CMS_PREVIEW_READ_PATH as c, STUDIO_BASE_PATH as d, STUDIO_COLLABORATION_PATH as f, CMS_DELIVERY_SITEMAP_PATH as i, CMS_READINESS_PATH as l, CMS_DELIVERY_QUERY_PATH as n, CMS_LIVENESS_PATH as o, STUDIO_HEALTH_PATH as p, CMS_DELIVERY_READ_PATH as r, CMS_PREVIEW_QUERY_PATH as s, CMS_AUTHENTICATION_PATH as t, STUDIO_API_PATH as u };
|
|
20
|
+
//# sourceMappingURL=HttpPaths-Be3vshPJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpPaths-Be3vshPJ.js","names":[],"sources":["../../../../protocol/src/HttpPaths.ts"],"sourcesContent":["export const STUDIO_BASE_PATH = '/_cms'\n\nexport const STUDIO_API_PATH = `${STUDIO_BASE_PATH}/api`\n\nexport const STUDIO_COLLABORATION_PATH = `${STUDIO_BASE_PATH}/collaboration`\n\nexport const STUDIO_HEALTH_PATH = `${STUDIO_BASE_PATH}/health`\n\nexport const CMS_AUTHENTICATION_PATH = '/api/cms/auth'\n\nexport const CMS_LIVENESS_PATH = `${STUDIO_HEALTH_PATH}/live`\n\nexport const CMS_READINESS_PATH = `${STUDIO_HEALTH_PATH}/ready`\n\nexport const CMS_DELIVERY_READ_PATH = `${STUDIO_API_PATH}/delivery/read`\n\nexport const CMS_DELIVERY_QUERY_PATH = `${STUDIO_API_PATH}/delivery/query`\n\nexport const CMS_DELIVERY_SEO_PATH = `${STUDIO_API_PATH}/delivery/seo`\n\nexport const CMS_DELIVERY_SITEMAP_PATH = `${STUDIO_API_PATH}/delivery/sitemap`\n\nexport const CMS_PREVIEW_READ_PATH = `${STUDIO_API_PATH}/preview/read`\n\nexport const CMS_PREVIEW_QUERY_PATH = `${STUDIO_API_PATH}/preview/query`\n\nexport const CMS_PREVIEW_SEO_PATH = `${STUDIO_API_PATH}/preview/seo`\n\nexport const CMS_FORM_SUBMIT_PATH = `${STUDIO_API_PATH}/forms/submit`\n"],"mappings":";AAAA,MAAa,mBAAmB;AAEhC,MAAa,kBAAkB,GAAG,iBAAiB;AAEnD,MAAa,4BAA4B,GAAG,iBAAiB;AAE7D,MAAa,qBAAqB,GAAG,iBAAiB;AAEtD,MAAa,0BAA0B;AAEvC,MAAa,oBAAoB,GAAG,mBAAmB;AAEvD,MAAa,qBAAqB,GAAG,mBAAmB;AAExD,MAAa,yBAAyB,GAAG,gBAAgB;AAEzD,MAAa,0BAA0B,GAAG,gBAAgB;AAE1D,MAAa,wBAAwB,GAAG,gBAAgB;AAExD,MAAa,4BAA4B,GAAG,gBAAgB;AAE5D,MAAa,wBAAwB,GAAG,gBAAgB;AAExD,MAAa,yBAAyB,GAAG,gBAAgB;AAEzD,MAAa,uBAAuB,GAAG,gBAAgB;AAEvD,MAAa,uBAAuB,GAAG,gBAAgB"}
|
|
@@ -5,7 +5,8 @@ interface CmsMessages {
|
|
|
5
5
|
interface CmsI18nOptions {
|
|
6
6
|
readonly defaultLocale: string;
|
|
7
7
|
readonly fallbackLocale?: string | null;
|
|
8
|
-
|
|
8
|
+
/** Prefix every localized route, including the default locale. */
|
|
9
|
+
readonly prefix?: 'always';
|
|
9
10
|
/** Select where CMS-derived locale metadata owns Nuxt Site Config. */
|
|
10
11
|
readonly siteConfig?: 'documents' | 'localized-routes';
|
|
11
12
|
readonly locales: Readonly<Record<string, {
|
|
@@ -26,4 +27,4 @@ type CmsMessageParameters<Key extends CmsMessageKey> = CmsI18nRegistry extends {
|
|
|
26
27
|
} ? Key extends keyof Parameters ? Parameters[Key] : never : Readonly<Record<string, string | number>>;
|
|
27
28
|
//#endregion
|
|
28
29
|
export { CmsMessageParameters as a, CmsMessageKey as i, CmsI18nRegistry as n, CmsMessages as o, CmsLocale as r, CmsI18nOptions as t };
|
|
29
|
-
//# sourceMappingURL=I18n-
|
|
30
|
+
//# sourceMappingURL=I18n-wxswIRyY.d.ts.map
|
package/src/I18n.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as CmsMessageParameters, i as CmsMessageKey, n as CmsI18nRegistry, o as CmsMessages, r as CmsLocale, t as CmsI18nOptions } from "./I18n-
|
|
1
|
+
import { a as CmsMessageParameters, i as CmsMessageKey, n as CmsI18nRegistry, o as CmsMessages, r as CmsLocale, t as CmsI18nOptions } from "./I18n-wxswIRyY.js";
|
|
2
2
|
export { CmsI18nOptions, CmsI18nRegistry, CmsLocale, CmsMessageKey, CmsMessageParameters, CmsMessages };
|
package/src/Module.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as
|
|
1
|
+
import { d as STUDIO_BASE_PATH, f as STUDIO_COLLABORATION_PATH, p as STUDIO_HEALTH_PATH, t as CMS_AUTHENTICATION_PATH, u as STUDIO_API_PATH } from "./HttpPaths-Be3vshPJ.js";
|
|
2
2
|
import { registerStudioApp } from "./internal/studio-app.js";
|
|
3
3
|
import { cmsAuthoringPlugin } from "./internal/authoring-compiler.js";
|
|
4
4
|
import { registerAuthoringCatalog } from "./internal/authoring-catalog.js";
|
|
@@ -6,8 +6,8 @@ import { loadCmsConfiguration } from "./internal/cms-config.js";
|
|
|
6
6
|
import { cmsRuntimeConfigurationDefaults, compileCmsConfiguration } from "./internal/configuration.js";
|
|
7
7
|
import { generateCmsApplicationTypes } from "./internal/application-types.js";
|
|
8
8
|
import { Effect, Layer } from "effect";
|
|
9
|
-
import { addComponent, addImports, addPlugin, addServerHandler, addServerPlugin, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, createResolver, defineNuxtModule, extendPages } from "@nuxt/kit";
|
|
10
9
|
import { NodeCrypto, NodeFileSystem, NodePath } from "@effect/platform-node-shared";
|
|
10
|
+
import { addComponent, addImports, addPlugin, addServerHandler, addServerPlugin, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, createResolver, defineNuxtModule, extendPages } from "@nuxt/kit";
|
|
11
11
|
|
|
12
12
|
//#region src/Module.ts
|
|
13
13
|
const CMS_SITEMAP_SOURCE_PATH = `${STUDIO_BASE_PATH}/sitemap`;
|
|
@@ -151,17 +151,6 @@ function configureNitro(nuxt) {
|
|
|
151
151
|
nuxt.hook("nitro:config", (config) => {
|
|
152
152
|
config.experimental ||= {};
|
|
153
153
|
config.experimental.websocket = true;
|
|
154
|
-
config.routeRules ||= {};
|
|
155
|
-
const studioRules = {
|
|
156
|
-
ssr: false,
|
|
157
|
-
headers: { "cache-control": "no-store" }
|
|
158
|
-
};
|
|
159
|
-
config.routeRules[`${STUDIO_APP_PATH}/**`] = studioRules;
|
|
160
|
-
config.routeRules[STUDIO_APP_PATH] = studioRules;
|
|
161
|
-
config.routeRules[STUDIO_BASE_PATH] = { redirect: {
|
|
162
|
-
statusCode: 302,
|
|
163
|
-
to: STUDIO_APP_PATH
|
|
164
|
-
} };
|
|
165
154
|
});
|
|
166
155
|
}
|
|
167
156
|
|
package/src/Module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Module.js","names":[],"sources":["../../../src/Module.ts"],"sourcesContent":["import type { HookResult, Nuxt } from '@nuxt/schema'\nimport type { NitroConfig } from 'nitropack/types'\nimport { registerStudioApp } from './internal/studio-app'\nimport { registerAuthoringCatalog } from './internal/authoring-catalog'\nimport { NodeCrypto, NodeFileSystem, NodePath } from '@effect/platform-node-shared'\nimport {\n CMS_AUTHENTICATION_PATH,\n STUDIO_APP_PATH,\n STUDIO_BASE_PATH,\n STUDIO_API_PATH,\n STUDIO_HEALTH_PATH,\n STUDIO_COLLABORATION_PATH,\n} from '@internal/protocol/HttpPaths'\nimport {\n addTemplate,\n addTypeTemplate,\n addComponent,\n addImports,\n addPlugin,\n addServerHandler,\n addServerPlugin,\n addServerTemplate,\n addVitePlugin,\n createResolver,\n defineNuxtModule,\n extendPages,\n} from '@nuxt/kit'\nimport { Effect, Layer } from 'effect'\nimport { loadCmsConfiguration } from './internal/cms-config'\nimport { cmsRuntimeConfigurationDefaults, compileCmsConfiguration } from './internal/configuration'\nimport { cmsAuthoringPlugin } from './internal/authoring-compiler'\nimport { generateCmsApplicationTypes } from './internal/application-types'\n\nconst CMS_SITEMAP_SOURCE_PATH = `${STUDIO_BASE_PATH}/sitemap`\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'nitro:config': (nitroConfig: NitroConfig) => HookResult\n }\n}\n\nconst resolver = createResolver(import.meta.url)\n\nconst nodeLayer = Layer.merge(NodeCrypto.layer, Layer.merge(NodeFileSystem.layer, NodePath.layer))\n\nconst cmsNuxtModule = defineNuxtModule({\n moduleDependencies: {\n '@nuxtjs/robots': {},\n '@nuxtjs/sitemap': {},\n '@comark/nuxt': {},\n 'nuxt-schema-org': {},\n 'nuxt-site-config': {},\n 'nuxt-seo-utils': {},\n },\n meta: {\n compatibility: { nuxt: '>=4.5.0 <5.0.0' },\n name: '@phtngyn/cms',\n },\n setup(_options, nuxt) {\n return Effect.runPromise(setupModule(nuxt).pipe(Effect.provide(nodeLayer)))\n },\n})\n\nexport default cmsNuxtModule\n\nconst setupModule = Effect.fn('CmsNuxtModule.setup')(function* (nuxt: Nuxt) {\n addVitePlugin(cmsAuthoringPlugin())\n const authored = yield* loadCmsConfiguration(nuxt.options.rootDir)\n const compiled = compileCmsConfiguration(authored.configuration)\n const i18n = compiled.i18n\n\n Object.assign(nuxt.options.runtimeConfig, {\n cms: cmsRuntimeConfigurationDefaults(authored.configuration, nuxt.options.runtimeConfig.cms),\n })\n\n configureSitemap(nuxt.options)\n\n const i18nTemplate = addTemplate({\n filename: 'cms/i18n.mjs',\n write: true,\n getContents: () => `export default JSON.parse(${JSON.stringify(JSON.stringify(i18n))})`,\n })\n\n nuxt.options.alias['#cms/i18n'] = i18nTemplate.dst\n let blockNames: ReadonlyArray<string> = []\n\n const applicationTypes = addTypeTemplate({\n filename: 'types/cms-application.d.ts',\n getContents: () => generateCmsApplicationTypes({ blockNames, configurationPath: authored.path, i18n }),\n })\n\n nuxt.options.alias['#cms/types'] = applicationTypes.dst\n nuxt.options.watch.push(authored.path)\n\n const authoring = yield* registerAuthoringCatalog(\n nuxt,\n compiled.documents,\n Object.fromEntries(\n Object.entries(authored.configuration.forms ?? {}).map(([name, form]) => [name, form.definition]),\n ),\n (names) => {\n blockNames = names\n },\n [applicationTypes.dst],\n )\n\n const installationPluginId = resolver.resolve('./runtime/plugin.virtual.mjs')\n\n const installationPluginTemplate = addServerTemplate({\n filename: installationPluginId,\n getContents: () =>\n [\n `import { createInstallationPlugin } from ${JSON.stringify(resolver.resolve('./runtime/plugin'))}`,\n `import cmsConfiguration from ${JSON.stringify(authored.path)}`,\n `import authoring from ${JSON.stringify(authoring.dst)}`,\n `export default createInstallationPlugin(cmsConfiguration, authoring)`,\n ].join('\\n'),\n })\n\n addServerHandler({ handler: resolver.resolve('./runtime/api'), route: `${STUDIO_HEALTH_PATH}/**:path` })\n addServerHandler({ handler: resolver.resolve('./runtime/sitemap'), route: CMS_SITEMAP_SOURCE_PATH })\n registerDeliveryUi(nuxt)\n yield* registerStudioApp(nuxt, resolver)\n configureNitro(nuxt)\n addServerPlugin(installationPluginTemplate.filename)\n addServerHandler({\n handler: resolver.resolve('./runtime/api'),\n route: `${CMS_AUTHENTICATION_PATH}/**:path`,\n })\n addServerHandler({\n handler: resolver.resolve('./runtime/collaboration'),\n route: STUDIO_COLLABORATION_PATH,\n })\n addServerHandler({\n handler: resolver.resolve('./runtime/api'),\n route: `${STUDIO_API_PATH}/**:path`,\n })\n})\n\ninterface CmsSitemapConfiguration {\n sources?: Array<unknown>\n}\n\ninterface CmsNuxtSitemapOptions {\n readonly modules?: unknown\n sitemap?: false | CmsSitemapConfiguration\n}\n\nfunction configureSitemap(options: CmsNuxtSitemapOptions): void {\n if (options.sitemap === false) return\n\n const sitemap = options.sitemap ?? {}\n const sources = sitemap.sources ?? []\n\n if (!sources.includes(CMS_SITEMAP_SOURCE_PATH)) sitemap.sources = [...sources, CMS_SITEMAP_SOURCE_PATH]\n\n options.sitemap = sitemap\n}\n\nfunction registerDeliveryUi(nuxt: Nuxt): void {\n addPlugin(resolver.resolve('./runtime/blocks'))\n nuxt.options.css.push(resolver.resolve('./runtime/preview/preview.css'))\n addComponent({ name: 'DocumentField', filePath: resolver.resolve('./runtime/delivery/DocumentField') })\n addComponent({ name: 'DocumentRenderer', filePath: resolver.resolve('./runtime/delivery/DocumentRenderer') })\n addComponent({ name: 'DocumentScope', filePath: resolver.resolve('./runtime/delivery/DocumentScope') })\n addPlugin(resolver.resolve('./runtime/delivery/plugin'))\n addPlugin(resolver.resolve('./runtime/preview/plugin.client'))\n addImports([\n { name: 'useCmsI18n', from: resolver.resolve('./runtime/i18n/useCmsI18n') },\n { name: 'useCmsForm', from: resolver.resolve('./runtime/forms/useCmsForm') },\n { name: 'useCmsDocumentSeo', from: resolver.resolve('./runtime/delivery/useCmsDocumentSeo') },\n { name: 'useDocument', from: resolver.resolve('./runtime/delivery/useDocument') },\n { name: 'useDocumentQuery', from: resolver.resolve('./runtime/delivery/useDocumentQuery') },\n ])\n extendPages((pages) => {\n pages.push({\n file: resolver.resolve('./runtime/delivery/document'),\n name: 'cms-document-page',\n path: '/:contentPath(.*)*',\n meta: { cmsDocument: true },\n })\n })\n}\n\nfunction configureNitro(nuxt: Nuxt): void {\n nuxt.hook('nitro:config', (config: NitroConfig) => {\n config.experimental ||= {}\n config.experimental.websocket = true\n config.routeRules ||= {}\n const studioRules = { ssr: false, headers: { 'cache-control': 'no-store' } }\n config.routeRules[`${STUDIO_APP_PATH}/**`] = studioRules\n config.routeRules[STUDIO_APP_PATH] = studioRules\n\n config.routeRules[STUDIO_BASE_PATH] = { redirect: { statusCode: 302, to: STUDIO_APP_PATH } }\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Module.js","names":[],"sources":["../../../src/Module.ts"],"sourcesContent":["import type { HookResult, Nuxt } from '@nuxt/schema'\nimport type { NitroConfig } from 'nitropack/types'\nimport { registerStudioApp } from './internal/studio-app'\nimport { registerAuthoringCatalog } from './internal/authoring-catalog'\nimport { NodeCrypto, NodeFileSystem, NodePath } from '@effect/platform-node-shared'\nimport {\n CMS_AUTHENTICATION_PATH,\n STUDIO_BASE_PATH,\n STUDIO_API_PATH,\n STUDIO_HEALTH_PATH,\n STUDIO_COLLABORATION_PATH,\n} from '@internal/protocol/HttpPaths'\nimport {\n addTemplate,\n addTypeTemplate,\n addComponent,\n addImports,\n addPlugin,\n addServerHandler,\n addServerPlugin,\n addServerTemplate,\n addVitePlugin,\n createResolver,\n defineNuxtModule,\n extendPages,\n} from '@nuxt/kit'\nimport { Effect, Layer } from 'effect'\nimport { loadCmsConfiguration } from './internal/cms-config'\nimport { cmsRuntimeConfigurationDefaults, compileCmsConfiguration } from './internal/configuration'\nimport { cmsAuthoringPlugin } from './internal/authoring-compiler'\nimport { generateCmsApplicationTypes } from './internal/application-types'\n\nconst CMS_SITEMAP_SOURCE_PATH = `${STUDIO_BASE_PATH}/sitemap`\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'nitro:config': (nitroConfig: NitroConfig) => HookResult\n }\n}\n\nconst resolver = createResolver(import.meta.url)\n\nconst nodeLayer = Layer.merge(NodeCrypto.layer, Layer.merge(NodeFileSystem.layer, NodePath.layer))\n\nconst cmsNuxtModule = defineNuxtModule({\n moduleDependencies: {\n '@nuxtjs/robots': {},\n '@nuxtjs/sitemap': {},\n '@comark/nuxt': {},\n 'nuxt-schema-org': {},\n 'nuxt-site-config': {},\n 'nuxt-seo-utils': {},\n },\n meta: {\n compatibility: { nuxt: '>=4.5.0 <5.0.0' },\n name: '@phtngyn/cms',\n },\n setup(_options, nuxt) {\n return Effect.runPromise(setupModule(nuxt).pipe(Effect.provide(nodeLayer)))\n },\n})\n\nexport default cmsNuxtModule\n\nconst setupModule = Effect.fn('CmsNuxtModule.setup')(function* (nuxt: Nuxt) {\n addVitePlugin(cmsAuthoringPlugin())\n const authored = yield* loadCmsConfiguration(nuxt.options.rootDir)\n const compiled = compileCmsConfiguration(authored.configuration)\n const i18n = compiled.i18n\n\n Object.assign(nuxt.options.runtimeConfig, {\n cms: cmsRuntimeConfigurationDefaults(authored.configuration, nuxt.options.runtimeConfig.cms),\n })\n\n configureSitemap(nuxt.options)\n\n const i18nTemplate = addTemplate({\n filename: 'cms/i18n.mjs',\n write: true,\n getContents: () => `export default JSON.parse(${JSON.stringify(JSON.stringify(i18n))})`,\n })\n\n nuxt.options.alias['#cms/i18n'] = i18nTemplate.dst\n let blockNames: ReadonlyArray<string> = []\n\n const applicationTypes = addTypeTemplate({\n filename: 'types/cms-application.d.ts',\n getContents: () => generateCmsApplicationTypes({ blockNames, configurationPath: authored.path, i18n }),\n })\n\n nuxt.options.alias['#cms/types'] = applicationTypes.dst\n nuxt.options.watch.push(authored.path)\n\n const authoring = yield* registerAuthoringCatalog(\n nuxt,\n compiled.documents,\n Object.fromEntries(\n Object.entries(authored.configuration.forms ?? {}).map(([name, form]) => [name, form.definition]),\n ),\n (names) => {\n blockNames = names\n },\n [applicationTypes.dst],\n )\n\n const installationPluginId = resolver.resolve('./runtime/plugin.virtual.mjs')\n\n const installationPluginTemplate = addServerTemplate({\n filename: installationPluginId,\n getContents: () =>\n [\n `import { createInstallationPlugin } from ${JSON.stringify(resolver.resolve('./runtime/plugin'))}`,\n `import cmsConfiguration from ${JSON.stringify(authored.path)}`,\n `import authoring from ${JSON.stringify(authoring.dst)}`,\n `export default createInstallationPlugin(cmsConfiguration, authoring)`,\n ].join('\\n'),\n })\n\n addServerHandler({ handler: resolver.resolve('./runtime/api'), route: `${STUDIO_HEALTH_PATH}/**:path` })\n addServerHandler({ handler: resolver.resolve('./runtime/sitemap'), route: CMS_SITEMAP_SOURCE_PATH })\n registerDeliveryUi(nuxt)\n yield* registerStudioApp(nuxt, resolver)\n configureNitro(nuxt)\n addServerPlugin(installationPluginTemplate.filename)\n addServerHandler({\n handler: resolver.resolve('./runtime/api'),\n route: `${CMS_AUTHENTICATION_PATH}/**:path`,\n })\n addServerHandler({\n handler: resolver.resolve('./runtime/collaboration'),\n route: STUDIO_COLLABORATION_PATH,\n })\n addServerHandler({\n handler: resolver.resolve('./runtime/api'),\n route: `${STUDIO_API_PATH}/**:path`,\n })\n})\n\ninterface CmsSitemapConfiguration {\n sources?: Array<unknown>\n}\n\ninterface CmsNuxtSitemapOptions {\n readonly modules?: unknown\n sitemap?: false | CmsSitemapConfiguration\n}\n\nfunction configureSitemap(options: CmsNuxtSitemapOptions): void {\n if (options.sitemap === false) return\n\n const sitemap = options.sitemap ?? {}\n const sources = sitemap.sources ?? []\n\n if (!sources.includes(CMS_SITEMAP_SOURCE_PATH)) sitemap.sources = [...sources, CMS_SITEMAP_SOURCE_PATH]\n\n options.sitemap = sitemap\n}\n\nfunction registerDeliveryUi(nuxt: Nuxt): void {\n addPlugin(resolver.resolve('./runtime/blocks'))\n nuxt.options.css.push(resolver.resolve('./runtime/preview/preview.css'))\n addComponent({ name: 'DocumentField', filePath: resolver.resolve('./runtime/delivery/DocumentField') })\n addComponent({ name: 'DocumentRenderer', filePath: resolver.resolve('./runtime/delivery/DocumentRenderer') })\n addComponent({ name: 'DocumentScope', filePath: resolver.resolve('./runtime/delivery/DocumentScope') })\n addPlugin(resolver.resolve('./runtime/delivery/plugin'))\n addPlugin(resolver.resolve('./runtime/preview/plugin.client'))\n addImports([\n { name: 'useCmsI18n', from: resolver.resolve('./runtime/i18n/useCmsI18n') },\n { name: 'useCmsForm', from: resolver.resolve('./runtime/forms/useCmsForm') },\n { name: 'useCmsDocumentSeo', from: resolver.resolve('./runtime/delivery/useCmsDocumentSeo') },\n { name: 'useDocument', from: resolver.resolve('./runtime/delivery/useDocument') },\n { name: 'useDocumentQuery', from: resolver.resolve('./runtime/delivery/useDocumentQuery') },\n ])\n extendPages((pages) => {\n pages.push({\n file: resolver.resolve('./runtime/delivery/document'),\n name: 'cms-document-page',\n path: '/:contentPath(.*)*',\n meta: { cmsDocument: true },\n })\n })\n}\n\nfunction configureNitro(nuxt: Nuxt): void {\n nuxt.hook('nitro:config', (config: NitroConfig) => {\n config.experimental ||= {}\n config.experimental.websocket = true\n })\n}\n"],"mappings":"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"}
|