@phtngyn/cms 0.2.0-beta.4 → 0.2.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -13
- package/package.json +7 -7
- package/src/ApplicationTypes.d.ts +3 -3
- package/src/Authoring.d.ts +11 -3
- package/src/{Configuration-BU-UyGoH.js → Configuration-JQ1qyaU0.js} +347 -189
- package/src/Configuration-JQ1qyaU0.js.map +1 -0
- package/src/Configuration.d.ts +1 -1
- package/src/Content.d.ts +7 -6
- package/src/Content.js +106 -47
- package/src/Content.js.map +1 -1
- package/src/ContentTransfer-BxwswWn3.js +86 -0
- package/src/ContentTransfer-BxwswWn3.js.map +1 -0
- package/src/{ContentTransfer-CRQet3QJ.d.ts → ContentTransfer-Z9FHyLez.d.ts} +33 -9
- package/src/{DocumentEngine-ClhFXW9M.js → DocumentEngine-j6Vi7nQo.js} +279 -178
- package/src/DocumentEngine-j6Vi7nQo.js.map +1 -0
- package/src/DocumentModel.d.ts +9 -2
- package/src/DocumentModel.js +17 -4
- package/src/DocumentModel.js.map +1 -1
- package/src/{Forms-DoB56hfe.js → Forms-CX-hwmJF.js} +18 -11
- package/src/Forms-CX-hwmJF.js.map +1 -0
- package/src/{Forms-BbkE7QfC.js → Forms-CfNPTiCr.js} +2 -2
- package/src/{Forms-BbkE7QfC.js.map → Forms-CfNPTiCr.js.map} +1 -1
- package/src/Media-j1bTritO.js +112 -0
- package/src/Media-j1bTritO.js.map +1 -0
- package/src/Module.js +0 -4
- package/src/Module.js.map +1 -1
- package/src/References-CCPDAPve.js +45 -0
- package/src/References-CCPDAPve.js.map +1 -0
- package/src/{S3MediaObjects-CR3p1WTg.js → S3MediaObjects-BRuPQbxl.js} +454 -516
- package/src/S3MediaObjects-BRuPQbxl.js.map +1 -0
- package/src/cli/content.js +6 -5
- package/src/cli/content.js.map +1 -1
- package/src/cli.js +16 -3
- package/src/cli.js.map +1 -1
- package/src/{connection-D5S9Iph-.js → connection-BP80q4d-.js} +2 -2
- package/src/{connection-D5S9Iph-.js.map → connection-BP80q4d-.js.map} +1 -1
- package/src/{dev-lifecycle-D3f9-upa.js → dev-lifecycle-DdBluSiR.js} +26 -6
- package/src/dev-lifecycle-DdBluSiR.js.map +1 -0
- package/src/{installation-fZtNxtoW.js → installation-BoG8E3nJ.js} +7982 -7155
- package/src/installation-BoG8E3nJ.js.map +1 -0
- package/src/internal/authoring-catalog.js +2 -2
- package/src/internal/authoring-compiler.js +35 -9
- package/src/internal/authoring-compiler.js.map +1 -1
- package/src/internal/authoring-metadata.js +14 -5
- package/src/internal/authoring-metadata.js.map +1 -1
- package/src/internal/configuration.js +27 -3
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/dev-lifecycle.js +2 -2
- package/src/internal/document-model.js +134 -43
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/field-metadata.js +2 -1
- package/src/internal/field-metadata.js.map +1 -1
- package/src/internal/form-capabilities.js +1 -1
- package/src/{location-CPX7oj0o.js → location-CMNGO3lU.js} +2 -2
- package/src/{location-CPX7oj0o.js.map → location-CMNGO3lU.js.map} +1 -1
- package/src/{metadata-BEZPWh-3.js → metadata-UzZmjwxM.js} +2 -2
- package/src/{metadata-BEZPWh-3.js.map → metadata-UzZmjwxM.js.map} +1 -1
- package/src/{models-C9kF9JlQ.js → models-5j67LMqW.js} +4 -4
- package/src/{models-C9kF9JlQ.js.map → models-5j67LMqW.js.map} +1 -1
- package/src/{models-ChRxBChy.js → models-VmGmG19-.js} +42 -130
- package/src/models-VmGmG19-.js.map +1 -0
- package/src/runtime/delivery/DocumentRenderer.js +5 -1
- package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
- package/src/runtime/delivery/context.js +1 -1
- package/src/runtime/delivery/plugin.js +2 -2
- package/src/runtime/delivery/preview.d.ts +1 -1
- package/src/runtime/delivery/types.d.ts +1 -1
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +1 -1
- package/src/runtime/forms/document.js +2 -2
- package/src/runtime/forms/useCmsForm.js +2 -2
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +1 -1
- package/src/runtime/preview/CmsStudioPreviewMarker.js +18 -4
- package/src/runtime/preview/CmsStudioPreviewMarker.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +65 -74
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/overlay.js +85 -28
- package/src/runtime/preview/overlay.js.map +1 -1
- package/src/runtime/preview/plugin.client.js +4 -4
- package/src/runtime/preview/preview.css +50 -36
- package/src/runtime/preview/protocol.d.ts +11 -5
- package/src/runtime/preview/protocol.js +17 -5
- package/src/runtime/preview/protocol.js.map +1 -1
- package/src/runtime/preview/regions.js +142 -0
- package/src/runtime/preview/regions.js.map +1 -0
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +9 -10
- package/src/runtime/sitemap.js.map +1 -1
- package/src/{scalars-B2lgGUnj.js → scalars-CVZqT3L0.js} +2 -6
- package/src/scalars-CVZqT3L0.js.map +1 -0
- package/src/{store-CCsjHaZm.js → store-PKKB8xa2.js} +49 -66
- package/src/store-PKKB8xa2.js.map +1 -0
- package/src/{types-DutFRtaG.d.ts → types-DZ0IV-Ow.d.ts} +14 -3
- package/studio/CreateDocumentDialog-vQ8hDs2C.js +253 -0
- package/studio/{documentPlanning-CDb31mnl.js → documentPlanning-Bx3W9KkD.js} +12054 -12085
- package/studio/{editor-Bzlh3zXt.js → editor-P2rB7Csp.js} +11228 -11927
- package/studio/host.css +1 -1
- package/studio/host.js +23594 -24903
- package/studio/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/src/Configuration-BU-UyGoH.js.map +0 -1
- package/src/ContentTransfer-BhF9G56s.js +0 -57
- package/src/ContentTransfer-BhF9G56s.js.map +0 -1
- package/src/DocumentEngine-ClhFXW9M.js.map +0 -1
- package/src/Forms-DoB56hfe.js.map +0 -1
- package/src/S3MediaObjects-CR3p1WTg.js.map +0 -1
- package/src/dev-lifecycle-D3f9-upa.js.map +0 -1
- package/src/installation-fZtNxtoW.js.map +0 -1
- package/src/models-ChRxBChy.js.map +0 -1
- package/src/runtime/preview/targets.js +0 -101
- package/src/runtime/preview/targets.js.map +0 -1
- package/src/scalars-B2lgGUnj.js.map +0 -1
- package/src/store-CCsjHaZm.js.map +0 -1
- package/studio/CreateDocumentDialog-DJ8c0WZb.js +0 -256
- package/studio/dom-to-image-more.min-D6jGGdrW.js +0 -877
- package/studio/rolldown-runtime-B0aSnxlc.js +0 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentEngine-j6Vi7nQo.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.prefixDefaultLocale)) {\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.prefixDefaultLocale)\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 prefixDefaultLocale: boolean,\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 || prefixDefaultLocale) ? 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 (prefixDefaultLocale) 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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"}
|
package/src/DocumentModel.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import { StandardJSONSchemaV1, StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
3
|
//#region src/DocumentModel.d.ts
|
|
4
|
-
export type CmsFieldInput = 'date' | 'multiselect' | 'number' | 'select' | 'text' | 'textarea' | 'toggle';
|
|
4
|
+
export type CmsFieldInput = 'date' | 'document' | 'image' | 'link' | 'media' | 'multiselect' | 'number' | 'select' | 'text' | 'textarea' | 'toggle';
|
|
5
5
|
export interface CmsFieldPresentation {
|
|
6
6
|
/** Use this encoded value only when the containing object key is absent. */
|
|
7
7
|
readonly default?: Schema.Json;
|
|
8
8
|
readonly description?: string;
|
|
9
9
|
readonly input?: CmsFieldInput;
|
|
10
10
|
readonly label?: string;
|
|
11
|
+
readonly options?: ReadonlyArray<{
|
|
12
|
+
readonly label: string;
|
|
13
|
+
readonly value: string | number;
|
|
14
|
+
}>;
|
|
11
15
|
}
|
|
12
16
|
export interface CmsCollectionOptions {
|
|
13
17
|
readonly body?: {
|
|
@@ -20,7 +24,6 @@ export interface CmsCollectionOptions {
|
|
|
20
24
|
readonly label: string;
|
|
21
25
|
readonly route: string;
|
|
22
26
|
readonly schema: CmsCollectionSchema;
|
|
23
|
-
readonly source?: string;
|
|
24
27
|
}
|
|
25
28
|
export interface CmsDocumentModelOptions {
|
|
26
29
|
readonly collections: Readonly<Record<string, CmsCollectionOptions>>;
|
|
@@ -41,5 +44,9 @@ export interface CmsSchemaOptions<Input, Output> {
|
|
|
41
44
|
export declare function defineCmsSchema<Input, Output>(options: CmsSchemaOptions<Input, Output>): StandardSchemaV1<Input, Output> & StandardJSONSchemaV1<Input, Output>;
|
|
42
45
|
/** A calendar date stored as YYYY-MM-DD, without converting document data to a Date. */
|
|
43
46
|
export declare const CalendarDate: Schema.String;
|
|
47
|
+
/** An identity-backed document selection stored in source and resolved to the catalog route at delivery. */
|
|
48
|
+
export declare const documentReference: Schema.decodeTo<Schema.String, Schema.brand<Schema.String, "AuthoredDocumentReference">, never, never>;
|
|
49
|
+
/** An identity-backed media-library selection stored in source and resolved to its public URL at delivery. */
|
|
50
|
+
export declare const managedMediaReference: Schema.decodeTo<Schema.String, Schema.brand<Schema.String, "ManagedMediaReference">, never, never>;
|
|
44
51
|
//#endregion
|
|
45
52
|
//# sourceMappingURL=DocumentModel.d.ts.map
|
package/src/DocumentModel.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { n as ManagedMediaReference, t as AuthoredDocumentReference } from "./References-CCPDAPve.js";
|
|
2
|
+
import { FIELD_INPUT_METADATA, FIELD_OPTIONS_METADATA } from "./internal/field-metadata.js";
|
|
3
|
+
import { DateTime, Effect, Option, Result, Schema, SchemaGetter } from "effect";
|
|
3
4
|
|
|
4
5
|
//#region src/DocumentModel.ts
|
|
5
6
|
function field(schema, presentation) {
|
|
@@ -7,6 +8,7 @@ function field(schema, presentation) {
|
|
|
7
8
|
...presentation.default === void 0 ? void 0 : { default: presentation.default },
|
|
8
9
|
...presentation.description === void 0 ? void 0 : { description: presentation.description },
|
|
9
10
|
...presentation.input === void 0 ? void 0 : { [FIELD_INPUT_METADATA]: presentation.input },
|
|
11
|
+
...presentation.options === void 0 ? void 0 : { [FIELD_OPTIONS_METADATA]: presentation.options },
|
|
10
12
|
...presentation.label === void 0 ? void 0 : { title: presentation.label }
|
|
11
13
|
}));
|
|
12
14
|
return presentation.default === void 0 ? annotated : annotated.pipe(Schema.withDecodingDefaultKey(Effect.succeed(presentation.default)));
|
|
@@ -27,7 +29,7 @@ function applyFieldPresentation(schema, fields) {
|
|
|
27
29
|
for (const [path, presentation] of Object.entries(fields)) {
|
|
28
30
|
let current = copy;
|
|
29
31
|
for (const segment of path.split(".")) {
|
|
30
|
-
const properties = current.properties;
|
|
32
|
+
const properties = (current.type === "array" && Schema.is(Schema.JsonObject)(current.items) ? current.items : current).properties;
|
|
31
33
|
const property = Schema.is(Schema.JsonObject)(properties) ? properties[segment] : void 0;
|
|
32
34
|
if (!Schema.is(Schema.JsonObject)(property)) throw new Error(`CMS field presentation path ${path} does not exist in the input JSON Schema.`);
|
|
33
35
|
current = property;
|
|
@@ -35,6 +37,7 @@ function applyFieldPresentation(schema, fields) {
|
|
|
35
37
|
if (presentation.description !== void 0) Object.assign(current, { description: presentation.description });
|
|
36
38
|
if (presentation.input !== void 0) Object.assign(current, { "x-cms-input": presentation.input });
|
|
37
39
|
if (presentation.label !== void 0) Object.assign(current, { title: presentation.label });
|
|
40
|
+
if (presentation.options !== void 0) Object.assign(current, { [FIELD_OPTIONS_METADATA]: presentation.options });
|
|
38
41
|
}
|
|
39
42
|
return copy;
|
|
40
43
|
}
|
|
@@ -47,7 +50,17 @@ const CalendarDate = Schema.String.annotate({ format: "date" }).check(Schema.mak
|
|
|
47
50
|
message: "Expected a valid date in YYYY-MM-DD format.",
|
|
48
51
|
toJsonSchema: () => ({})
|
|
49
52
|
}));
|
|
53
|
+
/** An identity-backed document selection stored in source and resolved to the catalog route at delivery. */
|
|
54
|
+
const documentReference = AuthoredDocumentReference.pipe(Schema.decodeTo(Schema.String, {
|
|
55
|
+
decode: SchemaGetter.passthroughSupertype(),
|
|
56
|
+
encode: SchemaGetter.passthroughSupertype()
|
|
57
|
+
}), Schema.annotateEncoded({ [FIELD_INPUT_METADATA]: "document" }));
|
|
58
|
+
/** An identity-backed media-library selection stored in source and resolved to its public URL at delivery. */
|
|
59
|
+
const managedMediaReference = ManagedMediaReference.pipe(Schema.decodeTo(Schema.String, {
|
|
60
|
+
decode: SchemaGetter.passthroughSupertype(),
|
|
61
|
+
encode: SchemaGetter.passthroughSupertype()
|
|
62
|
+
}), Schema.annotateEncoded({ [FIELD_INPUT_METADATA]: "media" }));
|
|
50
63
|
|
|
51
64
|
//#endregion
|
|
52
|
-
export { CalendarDate, defineCmsSchema, field };
|
|
65
|
+
export { CalendarDate, defineCmsSchema, documentReference, field, managedMediaReference };
|
|
53
66
|
//# sourceMappingURL=DocumentModel.js.map
|
package/src/DocumentModel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentModel.js","names":[],"sources":["../../../src/DocumentModel.ts"],"sourcesContent":["import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec'\nimport { DateTime, Effect, Option, Result, Schema } from 'effect'\nimport { FIELD_INPUT_METADATA } from './internal/field-metadata'\n\nexport type CmsFieldInput
|
|
1
|
+
{"version":3,"file":"DocumentModel.js","names":[],"sources":["../../../src/DocumentModel.ts"],"sourcesContent":["import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec'\nimport { AuthoredDocumentReference, ManagedMediaReference } from '@internal/protocol/References'\nimport { DateTime, Effect, Option, Result, Schema, SchemaGetter } from 'effect'\nimport { FIELD_INPUT_METADATA, FIELD_OPTIONS_METADATA } from './internal/field-metadata'\n\nexport type CmsFieldInput =\n | 'date'\n | 'document'\n | 'image'\n | 'link'\n | 'media'\n | 'multiselect'\n | 'number'\n | 'select'\n | 'text'\n | 'textarea'\n | 'toggle'\n\nexport interface CmsFieldPresentation {\n /** Use this encoded value only when the containing object key is absent. */\n readonly default?: Schema.Json\n readonly description?: string\n readonly input?: CmsFieldInput\n readonly label?: string\n readonly options?: ReadonlyArray<{ readonly label: string; readonly value: string | number }>\n}\n\nexport interface CmsCollectionOptions {\n readonly body?: {\n readonly blocks?: ReadonlyArray<string>\n readonly groups?: ReadonlyArray<string>\n }\n readonly canCreate?: boolean\n readonly description?: string\n readonly hierarchy?: boolean\n readonly label: string\n readonly route: string\n readonly schema: CmsCollectionSchema\n}\n\nexport interface CmsDocumentModelOptions {\n readonly collections: Readonly<Record<string, CmsCollectionOptions>>\n}\n\n/** Adds CMS presentation metadata without changing the schema's inferred input or output types. */\nexport function field<const FieldSchema extends Schema.Top & Schema.Constraint>(\n schema: FieldSchema,\n presentation: CmsFieldPresentation & { readonly default: FieldSchema['Encoded'] & Schema.Json },\n): Schema.withDecodingDefaultKey<FieldSchema>\nexport function field<const FieldSchema extends Schema.Top & Schema.Constraint>(\n schema: FieldSchema,\n presentation: CmsFieldPresentation,\n): FieldSchema['Rebuild']\nexport function field(\n schema: Schema.Top & Schema.Constraint,\n presentation: CmsFieldPresentation,\n): Schema.Top & Schema.Constraint {\n const annotated = schema.pipe(\n Schema.annotateEncoded({\n ...(presentation.default === undefined ? undefined : { default: presentation.default }),\n ...(presentation.description === undefined ? undefined : { description: presentation.description }),\n ...(presentation.input === undefined ? undefined : { [FIELD_INPUT_METADATA]: presentation.input }),\n ...(presentation.options === undefined ? undefined : { [FIELD_OPTIONS_METADATA]: presentation.options }),\n ...(presentation.label === undefined ? undefined : { title: presentation.label }),\n }),\n )\n\n return presentation.default === undefined\n ? annotated\n : annotated.pipe(Schema.withDecodingDefaultKey(Effect.succeed(presentation.default)))\n}\n\n/** Effect schemas work directly; other libraries supply validation and input JSON Schema. */\nexport type CmsCollectionSchema = Schema.ConstraintDecoder<unknown> | (StandardSchemaV1 & StandardJSONSchemaV1)\n\nexport interface CmsSchemaOptions<Input, Output> {\n readonly validator: StandardSchemaV1<Input, Output>\n readonly jsonSchema: StandardJSONSchemaV1<Input, Output>['~standard']['jsonSchema']\n readonly fields?: Readonly<Record<string, CmsFieldPresentation>>\n}\n\ntype JsonSchema = ReturnType<StandardJSONSchemaV1['~standard']['jsonSchema']['input']>\n\n/** Combines library-neutral validation, JSON Schema conversion, and CMS field presentation. */\nexport function defineCmsSchema<Input, Output>(\n options: CmsSchemaOptions<Input, Output>,\n): StandardSchemaV1<Input, Output> & StandardJSONSchemaV1<Input, Output> {\n return {\n '~standard': {\n ...options.validator['~standard'],\n jsonSchema: {\n input: (conversion) => applyFieldPresentation(options.jsonSchema.input(conversion), options.fields),\n output: options.jsonSchema.output,\n },\n },\n }\n}\n\nfunction applyFieldPresentation(\n schema: JsonSchema,\n fields?: Readonly<Record<string, CmsFieldPresentation>>,\n): JsonSchema {\n if (!fields) return schema\n const copy = Result.getOrThrow(Schema.decodeUnknownResult(Schema.JsonObject)(structuredClone(schema)))\n\n for (const [path, presentation] of Object.entries(fields)) {\n let current: Schema.JsonObject = copy\n\n for (const segment of path.split('.')) {\n const container =\n current.type === 'array' && Schema.is(Schema.JsonObject)(current.items) ? current.items : current\n\n const properties = container.properties\n const property = Schema.is(Schema.JsonObject)(properties) ? properties[segment] : undefined\n\n if (!Schema.is(Schema.JsonObject)(property)) {\n throw new Error(`CMS field presentation path ${path} does not exist in the input JSON Schema.`)\n }\n\n current = property\n }\n\n if (presentation.description !== undefined) Object.assign(current, { description: presentation.description })\n\n if (presentation.input !== undefined) Object.assign(current, { 'x-cms-input': presentation.input })\n\n if (presentation.label !== undefined) Object.assign(current, { title: presentation.label })\n\n if (presentation.options !== undefined) Object.assign(current, { [FIELD_OPTIONS_METADATA]: presentation.options })\n }\n\n return copy\n}\n\n/** A calendar date stored as YYYY-MM-DD, without converting document data to a Date. */\nexport const CalendarDate = Schema.String.annotate({ format: 'date' }).check(\n Schema.makeFilter(\n (value) => {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/u.test(value)) return false\n const parsed = DateTime.make(value)\n\n return Option.isSome(parsed) && DateTime.formatIsoDate(parsed.value) === value\n },\n { message: 'Expected a valid date in YYYY-MM-DD format.', toJsonSchema: () => ({}) },\n ),\n)\n\n/** An identity-backed document selection stored in source and resolved to the catalog route at delivery. */\nexport const documentReference = AuthoredDocumentReference.pipe(\n Schema.decodeTo(Schema.String, {\n decode: SchemaGetter.passthroughSupertype<AuthoredDocumentReference, string>(),\n encode: SchemaGetter.passthroughSupertype<AuthoredDocumentReference, string>(),\n }),\n Schema.annotateEncoded({ [FIELD_INPUT_METADATA]: 'document' }),\n)\n\n/** An identity-backed media-library selection stored in source and resolved to its public URL at delivery. */\nexport const managedMediaReference = ManagedMediaReference.pipe(\n Schema.decodeTo(Schema.String, {\n decode: SchemaGetter.passthroughSupertype<ManagedMediaReference, string>(),\n encode: SchemaGetter.passthroughSupertype<ManagedMediaReference, string>(),\n }),\n Schema.annotateEncoded({ [FIELD_INPUT_METADATA]: 'media' }),\n)\n"],"mappings":";;;;;AAqDA,SAAgB,MACd,QACA,cACgC;CAChC,MAAM,YAAY,OAAO,KACvB,OAAO,gBAAgB;EACrB,GAAI,aAAa,YAAY,SAAY,SAAY,EAAE,SAAS,aAAa,QAAQ;EACrF,GAAI,aAAa,gBAAgB,SAAY,SAAY,EAAE,aAAa,aAAa,YAAY;EACjG,GAAI,aAAa,UAAU,SAAY,SAAY,GAAG,uBAAuB,aAAa,MAAM;EAChG,GAAI,aAAa,YAAY,SAAY,SAAY,GAAG,yBAAyB,aAAa,QAAQ;EACtG,GAAI,aAAa,UAAU,SAAY,SAAY,EAAE,OAAO,aAAa,MAAM;CACjF,CAAC,CACH;CAEA,OAAO,aAAa,YAAY,SAC5B,YACA,UAAU,KAAK,OAAO,uBAAuB,OAAO,QAAQ,aAAa,OAAO,CAAC,CAAC;AACxF;;AAcA,SAAgB,gBACd,SACuE;CACvE,OAAO,EACL,aAAa;EACX,GAAG,QAAQ,UAAU;EACrB,YAAY;GACV,QAAQ,eAAe,uBAAuB,QAAQ,WAAW,MAAM,UAAU,GAAG,QAAQ,MAAM;GAClG,QAAQ,QAAQ,WAAW;EAC7B;CACF,EACF;AACF;AAEA,SAAS,uBACP,QACA,QACY;CACZ,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,OAAO,OAAO,WAAW,OAAO,oBAAoB,OAAO,UAAU,CAAC,CAAC,gBAAgB,MAAM,CAAC,CAAC;CAErG,KAAK,MAAM,CAAC,MAAM,iBAAiB,OAAO,QAAQ,MAAM,GAAG;EACzD,IAAI,UAA6B;EAEjC,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;GAIrC,MAAM,cAFJ,QAAQ,SAAS,WAAW,OAAO,GAAG,OAAO,UAAU,CAAC,CAAC,QAAQ,KAAK,IAAI,QAAQ,QAAQ,QAEhE,CAAC;GAC7B,MAAM,WAAW,OAAO,GAAG,OAAO,UAAU,CAAC,CAAC,UAAU,IAAI,WAAW,WAAW;GAElF,IAAI,CAAC,OAAO,GAAG,OAAO,UAAU,CAAC,CAAC,QAAQ,GACxC,MAAM,IAAI,MAAM,+BAA+B,KAAK,0CAA0C;GAGhG,UAAU;EACZ;EAEA,IAAI,aAAa,gBAAgB,QAAW,OAAO,OAAO,SAAS,EAAE,aAAa,aAAa,YAAY,CAAC;EAE5G,IAAI,aAAa,UAAU,QAAW,OAAO,OAAO,SAAS,EAAE,eAAe,aAAa,MAAM,CAAC;EAElG,IAAI,aAAa,UAAU,QAAW,OAAO,OAAO,SAAS,EAAE,OAAO,aAAa,MAAM,CAAC;EAE1F,IAAI,aAAa,YAAY,QAAW,OAAO,OAAO,SAAS,GAAG,yBAAyB,aAAa,QAAQ,CAAC;CACnH;CAEA,OAAO;AACT;;AAGA,MAAa,eAAe,OAAO,OAAO,SAAS,EAAE,QAAQ,OAAO,CAAC,CAAC,CAAC,MACrE,OAAO,YACJ,UAAU;CACT,IAAI,CAAC,uBAAuB,KAAK,KAAK,GAAG,OAAO;CAChD,MAAM,SAAS,SAAS,KAAK,KAAK;CAElC,OAAO,OAAO,OAAO,MAAM,KAAK,SAAS,cAAc,OAAO,KAAK,MAAM;AAC3E,GACA;CAAE,SAAS;CAA+C,qBAAqB,CAAC;AAAG,CACrF,CACF;;AAGA,MAAa,oBAAoB,0BAA0B,KACzD,OAAO,SAAS,OAAO,QAAQ;CAC7B,QAAQ,aAAa,qBAAwD;CAC7E,QAAQ,aAAa,qBAAwD;AAC/E,CAAC,GACD,OAAO,gBAAgB,GAAG,uBAAuB,WAAW,CAAC,CAC/D;;AAGA,MAAa,wBAAwB,sBAAsB,KACzD,OAAO,SAAS,OAAO,QAAQ;CAC7B,QAAQ,aAAa,qBAAoD;CACzE,QAAQ,aAAa,qBAAoD;AAC3E,CAAC,GACD,OAAO,gBAAgB,GAAG,uBAAuB,QAAQ,CAAC,CAC5D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as CmsMarkdownDocument } from "./models-
|
|
2
|
-
import { a as FormOption, i as FormFieldType, s as FormSteps, t as FORM_REVISION_MAX_BYTES } from "./Forms-
|
|
1
|
+
import { n as CmsMarkdownDocument } from "./models-VmGmG19-.js";
|
|
2
|
+
import { a as FormOption, i as FormFieldType, s as FormSteps, t as FORM_REVISION_MAX_BYTES } from "./Forms-CfNPTiCr.js";
|
|
3
3
|
import { Option, Predicate, Result, Schema } from "effect";
|
|
4
4
|
import { resolveAttributes, textContent } from "comark/utils";
|
|
5
5
|
|
|
@@ -155,7 +155,9 @@ function matchesCmsComponentPropType(value, type) {
|
|
|
155
155
|
case "array": return Array.isArray(value);
|
|
156
156
|
case "boolean": return Predicate.isBoolean(value);
|
|
157
157
|
case "number": return Predicate.isNumber(value);
|
|
158
|
-
case "string":
|
|
158
|
+
case "string":
|
|
159
|
+
case "date": return Predicate.isString(value);
|
|
160
|
+
case "string[]": return Array.isArray(value) && value.every(Predicate.isString);
|
|
159
161
|
}
|
|
160
162
|
}
|
|
161
163
|
function normalizeComponentNode(node, components) {
|
|
@@ -196,8 +198,12 @@ function sameJson(left, right) {
|
|
|
196
198
|
//#endregion
|
|
197
199
|
//#region ../document/src/Forms.ts
|
|
198
200
|
function formStructureIssues(input, capabilities, name) {
|
|
201
|
+
const parsed = parseFormSteps(input, capabilities, name);
|
|
202
|
+
return Result.isFailure(parsed) ? parsed.failure : [];
|
|
203
|
+
}
|
|
204
|
+
function parseFormSteps(input, capabilities, name) {
|
|
199
205
|
const decoded = Schema.decodeUnknownResult(DraftFormSteps)(input, { onExcessProperty: "error" });
|
|
200
|
-
if (Result.isFailure(decoded)) return ["Each form needs steps with a title and at least one valid question."];
|
|
206
|
+
if (Result.isFailure(decoded)) return Result.fail(["Each form needs steps with a title and at least one valid question."]);
|
|
201
207
|
const issues = [];
|
|
202
208
|
if (new TextEncoder().encode(JSON.stringify(formRevision(name, capabilities, decoded.success))).byteLength > 6e4) issues.push("This form is too large. Reduce the number or size of questions.");
|
|
203
209
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -234,7 +240,8 @@ function formStructureIssues(input, capabilities, name) {
|
|
|
234
240
|
if (field.type !== "select" && options.length) issues.push(`${field.label}: choices require a select question.`);
|
|
235
241
|
}
|
|
236
242
|
}
|
|
237
|
-
return issues;
|
|
243
|
+
if (issues.length) return Result.fail(issues);
|
|
244
|
+
return Schema.decodeUnknownResult(FormSteps)(decoded.success).pipe(Result.mapError(() => ["Each form needs steps with a title and at least one valid question."]));
|
|
238
245
|
}
|
|
239
246
|
function validateFormValues(fields, values) {
|
|
240
247
|
return Object.fromEntries(fields.flatMap((field) => {
|
|
@@ -283,15 +290,15 @@ function documentForms(document, components, preview = false) {
|
|
|
283
290
|
const nodePath = [...parent, index];
|
|
284
291
|
const projection = projectCmsEditorComponentAttributes(node[1], renderData);
|
|
285
292
|
const capabilities = components.find((component) => component.name === node[0])?.authoring.form;
|
|
286
|
-
if (capabilities
|
|
287
|
-
const
|
|
288
|
-
forms.push({
|
|
293
|
+
if (capabilities) {
|
|
294
|
+
const parsed = parseFormSteps(projection.props.steps, capabilities, node[0]);
|
|
295
|
+
if (Result.isSuccess(parsed)) forms.push({
|
|
289
296
|
name: node[0],
|
|
290
297
|
documentId: document.id,
|
|
291
298
|
nodePath,
|
|
292
|
-
steps,
|
|
299
|
+
steps: parsed.success,
|
|
293
300
|
preview,
|
|
294
|
-
revision: formRevision(node[0], capabilities,
|
|
301
|
+
revision: formRevision(node[0], capabilities, parsed.success)
|
|
295
302
|
});
|
|
296
303
|
}
|
|
297
304
|
visit(node.slice(2).filter(isNode), nodePath, projection.renderData);
|
|
@@ -381,4 +388,4 @@ function formAuthoring(capabilities) {
|
|
|
381
388
|
|
|
382
389
|
//#endregion
|
|
383
390
|
export { encodeCmsEditorComponentAttributes as a, resolveCmsComarkAttributes as c, createCmsComarkRenderData as d, mutableJson as f, validateFormValues as i, withCmsComarkProps as l, toComarkDocument as m, formAuthoring as n, normalizeCmsComponentBindings as o, mutableJsonObject as p, formStructureIssues as r, projectCmsEditorComponentAttributes as s, documentForms as t, cmsComarkTextContent as u };
|
|
384
|
-
//# sourceMappingURL=Forms-
|
|
391
|
+
//# sourceMappingURL=Forms-CX-hwmJF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Forms-CX-hwmJF.js","names":["isJsonObject","jsonObject","CmsMarkdownDocumentSchema","FormFieldTypeSchema","FormOptionSchema"],"sources":["../../../../document/src/internal/comark/document-adapter.ts","../../../../document/src/internal/comark/bindings.ts","../../../../document/src/Forms.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type {\n ElementNodeAttributes,\n MarkdownDocument as ComarkMarkdownDocument,\n Node as ComarkNode,\n NodeRenderData,\n} from 'comark'\nimport { textContent } from 'comark/utils'\nimport { Predicate, Schema } from 'effect'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\nexport function toComarkDocument(document: CmsMarkdownDocument): ComarkMarkdownDocument {\n return {\n frontmatter: mutableJsonObject(document.frontmatter),\n meta: mutableJsonObject(document.meta),\n nodes: document.nodes.map(toComarkNode),\n }\n}\n\nexport function createCmsComarkRenderData(document: CmsMarkdownDocument): NodeRenderData {\n return {\n data: {},\n frontmatter: mutableJsonObject(document.frontmatter),\n meta: mutableJsonObject(document.meta),\n props: {},\n }\n}\n\n/** Extracts inline text with Comark semantics, preserving punctuation between nested inline nodes. */\nexport function cmsComarkTextContent(node: MarkdownNode): string {\n return textContent(toComarkNode(node), { decodeUnicodeEntities: true })\n}\n\nexport function toMutableComarkAttributes(attributes: Schema.JsonObject): ElementNodeAttributes {\n const result: ElementNodeAttributes = {}\n\n for (const [name, value] of Object.entries(attributes)) {\n if (name !== '$') result[name] = mutableJson(value)\n }\n\n const internal = jsonObject(attributes.$)\n const line = internal.line\n const html = binaryFlag(internal.html)\n const block = binaryFlag(internal.block)\n\n if (Predicate.isNumber(line) || html !== undefined || block !== undefined) {\n const metadata: Record<string, number> = {}\n\n if (Predicate.isNumber(line)) metadata.line = line\n\n if (html !== undefined) metadata.html = html\n\n if (block !== undefined) metadata.block = block\n result.$ = metadata\n }\n\n return result\n}\n\nexport function mutableJson(value: Schema.Json): Schema.Json {\n if (Array.isArray(value)) return value.map(mutableJson)\n\n if (isJsonObject(value)) return mutableJsonObject(value)\n\n return value\n}\n\nfunction toComarkNode(node: MarkdownNode): ComarkNode {\n if (Predicate.isString(node)) return node\n\n if (node[0] === null) return [null, toMutableComarkAttributes(node[1]), node[2]]\n const [tag, attributes, ...children] = node\n\n return [tag, toMutableComarkAttributes(attributes), ...children.map(toComarkNode)]\n}\n\nexport function mutableJsonObject(value: Schema.JsonObject): Record<string, Schema.Json> {\n return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, mutableJson(child)]))\n}\n\nfunction binaryFlag(value: Schema.Json | undefined): 0 | 1 | undefined {\n return value === 0 || value === 1 ? value : undefined\n}\n\nfunction jsonObject(value: Schema.Json | undefined): Schema.JsonObject {\n return isJsonObject(value) ? value : {}\n}\n","import type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { NodeRenderData } from 'comark'\nimport { CmsMarkdownDocument as CmsMarkdownDocumentSchema } from '@internal/protocol/Documents'\nimport { resolveAttributes } from 'comark/utils'\nimport { Option, Predicate, Schema } from 'effect'\nimport { mutableJson, mutableJsonObject, toMutableComarkAttributes } from './document-adapter'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\nconst decodeJson = Schema.decodeUnknownOption(Schema.Json)\n\nexport type CmsComarkAttributeValue = Schema.Json | undefined\n\nexport type CmsComarkAttributes = ReadonlyMap<string, CmsComarkAttributeValue>\n\ninterface CmsEditorComponentProjection {\n readonly bindings: Schema.JsonObject\n readonly props: Schema.JsonObject\n readonly renderData: NodeRenderData\n}\n\n/** Normalizes bindings exactly as Comark's framework renderers do before passing props to a component. */\nexport function resolveCmsComarkAttributes(\n attributes: Schema.JsonObject,\n renderData: NodeRenderData,\n): CmsComarkAttributes {\n const resolved = new Map<string, CmsComarkAttributeValue>()\n\n for (const [name, value] of Object.entries(\n resolveAttributes(toMutableComarkAttributes(attributes), renderData, { parseJson: true }),\n )) {\n if (Predicate.isUndefined(value)) {\n resolved.set(name, undefined)\n continue\n }\n\n const decoded = decodeJson(value)\n\n if (Option.isNone(decoded)) throw new Error(`Comark resolved non-JSON attribute \"${name}\".`)\n resolved.set(name, decoded.value)\n }\n\n return resolved\n}\n\n/** Projects bindings to editable values while retaining enough metadata to reconstruct their authored form. */\nexport function projectCmsEditorComponentAttributes(\n attributes: Schema.JsonObject,\n renderData: NodeRenderData,\n): CmsEditorComponentProjection {\n const resolved = resolveCmsComarkAttributes(attributes, renderData)\n const props: Record<string, Schema.Json> = {}\n\n for (const [name, value] of resolved) {\n if (!Predicate.isUndefined(value)) props[name] = mutableJson(value)\n }\n\n const bindings: Record<string, Schema.Json> = {}\n\n for (const [authoredName, authoredValue] of Object.entries(attributes)) {\n if (!authoredName.startsWith(':') || authoredName.length === 1) continue\n const name = authoredName.slice(1)\n\n if (!resolved.has(name)) continue\n const literal = jsonLiteral(authoredValue)\n\n if (!Predicate.isString(authoredValue) || literal !== authoredValue) {\n bindings[name] = { kind: 'literal' }\n continue\n }\n\n const resolvedValue = resolved.get(name)\n bindings[name] = Object.assign(\n { expression: authoredValue, kind: 'expression' },\n Predicate.isUndefined(resolvedValue) ? undefined : { resolved: mutableJson(resolvedValue) },\n )\n }\n\n return { bindings, props, renderData: withCmsComarkProps(renderData, resolved) }\n}\n\n/** Reconstructs authored bindings, keeping expressions until a user replaces their resolved value. */\nexport function encodeCmsEditorComponentAttributes(\n props: Schema.JsonObject,\n bindings: Schema.JsonObject,\n): Schema.JsonObject {\n const attributes = mutableJsonObject(props)\n\n for (const [name, encodedBinding] of Object.entries(bindings)) {\n const binding = jsonObject(encodedBinding)\n const kind = binding.kind\n\n if (kind !== 'literal' && kind !== 'expression') continue\n const current = props[name]\n\n if (Predicate.isUndefined(current)) {\n const expression = binding.expression\n\n if (kind === 'expression' && Predicate.isString(expression)) attributes[`:${name}`] = expression\n continue\n }\n\n delete attributes[name]\n const expression = binding.expression\n const resolved = binding.resolved\n attributes[`:${name}`] =\n kind === 'expression' &&\n Predicate.isString(expression) &&\n Object.hasOwn(binding, 'resolved') &&\n sameJson(current, resolved)\n ? expression\n : mutableJson(current)\n }\n\n return attributes\n}\n\nexport function withCmsComarkProps(renderData: NodeRenderData, attributes: CmsComarkAttributes): NodeRenderData {\n return attributes.size > 0 ? { ...renderData, props: Object.fromEntries(attributes) } : renderData\n}\n\n/** Restores typed component bindings that Comark's block-YAML roundtrip can emit as plain attributes. */\nexport function normalizeCmsComponentBindings(\n document: CmsMarkdownDocument,\n components: ReadonlyMap<string, ComponentDefinition> | undefined,\n): CmsMarkdownDocument {\n if (!components) return document\n\n return CmsMarkdownDocumentSchema.make({\n frontmatter: document.frontmatter,\n meta: document.meta,\n nodes: document.nodes.map((node) => normalizeComponentNode(node, components)),\n })\n}\n\nexport function matchesCmsComponentPropType(\n value: CmsComarkAttributeValue,\n type: ComponentDefinition['authoring']['props'][number]['type'],\n): boolean {\n switch (type) {\n case 'object':\n return isJsonObject(value)\n case 'array':\n return Array.isArray(value)\n case 'boolean':\n return Predicate.isBoolean(value)\n case 'number':\n return Predicate.isNumber(value)\n case 'string':\n case 'date':\n return Predicate.isString(value)\n case 'string[]':\n return Array.isArray(value) && value.every(Predicate.isString)\n }\n}\n\nfunction normalizeComponentNode(\n node: MarkdownNode,\n components: ReadonlyMap<string, ComponentDefinition>,\n): MarkdownNode {\n if (Predicate.isString(node) || node[0] === null) return node\n const [tag, originalAttributes, ...originalChildren] = node\n const attributes = mutableJsonObject(originalAttributes)\n const definition = components.get(tag.toLocaleLowerCase())\n\n if (definition) {\n for (const prop of definition.authoring.props) {\n if (prop.type === 'string' || `:${prop.name}` in attributes || !(prop.name in attributes)) continue\n const value = attributes[prop.name]\n\n if (Predicate.isUndefined(value)) continue\n const resolved = jsonLiteral(value)\n\n if (!matchesCmsComponentPropType(resolved, prop.type)) continue\n delete attributes[prop.name]\n attributes[`:${prop.name}`] = value\n }\n }\n\n return [tag, attributes, ...originalChildren.map((child) => normalizeComponentNode(child, components))]\n}\n\nfunction jsonLiteral(value: Schema.Json | undefined): CmsComarkAttributeValue {\n if (!Predicate.isString(value)) return value\n\n try {\n const decoded = decodeJson(JSON.parse(value))\n\n return Option.isSome(decoded) ? decoded.value : value\n } catch {\n return value\n }\n}\n\nfunction jsonObject(value: Schema.Json | undefined): Schema.JsonObject {\n return isJsonObject(value) ? value : {}\n}\n\nfunction sameJson(left: Schema.Json, right: Schema.Json | undefined): boolean {\n return !Predicate.isUndefined(right) && JSON.stringify(left) === JSON.stringify(right)\n}\n","import { createCmsComarkRenderData } from './internal/comark/document-adapter'\nimport { projectCmsEditorComponentAttributes } from './internal/comark/bindings'\nimport type { NodeRenderData } from 'comark'\nimport type { BlockAuthoring } from '@internal/protocol/Authoring'\nimport type { StructuredField } from '@internal/protocol/StructuredFields'\nimport type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { CmsMarkdownDocument } from '@internal/protocol/Documents'\nimport type {\n FormCapabilities,\n FormDefinition,\n FormField,\n FormFieldType,\n FormOption,\n FormStep,\n FormValues,\n} from '@internal/protocol/Forms'\nimport {\n FORM_REVISION_MAX_BYTES,\n FormFieldType as FormFieldTypeSchema,\n FormOption as FormOptionSchema,\n FormSteps,\n} from '@internal/protocol/Forms'\nimport { Predicate, Result, Schema } from 'effect'\n\nexport function formStructureIssues(\n input: Schema.Json | undefined,\n capabilities: FormCapabilities,\n name: string,\n): string[] {\n const parsed = parseFormSteps(input, capabilities, name)\n\n return Result.isFailure(parsed) ? parsed.failure : []\n}\n\nfunction parseFormSteps(\n input: Schema.Json | undefined,\n capabilities: FormCapabilities,\n name: string,\n): Result.Result<ReadonlyArray<FormStep>, string[]> {\n const decoded = Schema.decodeUnknownResult(DraftFormSteps)(input, { onExcessProperty: 'error' })\n\n if (Result.isFailure(decoded))\n return Result.fail(['Each form needs steps with a title and at least one valid question.'])\n const issues: string[] = []\n const revisionBytes = new TextEncoder().encode(JSON.stringify(formRevision(name, capabilities, decoded.success)))\n\n if (revisionBytes.byteLength > FORM_REVISION_MAX_BYTES)\n issues.push('This form is too large. Reduce the number or size of questions.')\n const ids = new Set<string>()\n\n for (const step of decoded.success) {\n if (ids.has(step.id)) issues.push('Steps and questions must have unique identities.')\n ids.add(step.id)\n\n for (const field of step.fields) {\n if (ids.has(field.id)) issues.push('Steps and questions must have unique identities.')\n ids.add(field.id)\n\n if (['_form', '__proto__', 'constructor', 'prototype'].includes(field.id))\n issues.push('This question identity is reserved.')\n\n if (!capabilities.fieldTypes.includes(field.type))\n issues.push(`${field.label}: this question type is unavailable.`)\n\n for (const rule of ['required', 'minLength', 'maxLength', 'min', 'max'] as const) {\n if (field[rule] !== undefined && !capabilities.rules.includes(rule))\n issues.push(`${field.label}: ${rule} is unavailable.`)\n }\n\n const text = ['text', 'email', 'textarea'].includes(field.type)\n\n if (!text && (field.minLength !== undefined || field.maxLength !== undefined))\n issues.push(`${field.label}: length limits require a text question.`)\n\n if (field.type !== 'number' && (field.min !== undefined || field.max !== undefined))\n issues.push(`${field.label}: numeric limits require a number question.`)\n\n if (field.min !== undefined && field.max !== undefined && field.min > field.max)\n issues.push(`${field.label}: minimum exceeds maximum.`)\n\n if (field.minLength !== undefined && field.maxLength !== undefined && field.minLength > field.maxLength)\n issues.push(`${field.label}: minimum length exceeds maximum length.`)\n const options = field.options ?? []\n\n if (\n field.type === 'select' &&\n (!options.length || new Set(options.map((option) => option.id)).size !== options.length)\n )\n issues.push(`${field.label}: choices need unique identities and at least one option.`)\n\n if (field.type !== 'select' && options.length) issues.push(`${field.label}: choices require a select question.`)\n }\n }\n\n if (issues.length) return Result.fail(issues)\n\n return Schema.decodeUnknownResult(FormSteps)(decoded.success).pipe(\n Result.mapError(() => ['Each form needs steps with a title and at least one valid question.']),\n )\n}\n\nexport function validateFormValues(fields: ReadonlyArray<FormField>, values: FormValues): Record<string, string> {\n return Object.fromEntries(\n fields.flatMap((field) => {\n const issue = fieldIssue(field, Object.hasOwn(values, field.id) ? values[field.id] : undefined)\n\n return issue ? [[field.id, issue]] : []\n }),\n )\n}\n\nfunction fieldIssue(field: FormField, value: FormValues[string] | undefined): string | undefined {\n const empty = value === undefined || value === null || value === '' || (Predicate.isString(value) && !value.trim())\n\n if (empty) return field.required ? `${field.label} is required.` : undefined\n\n if (field.type === 'checkbox')\n return !Predicate.isBoolean(value)\n ? 'Choose yes or no.'\n : field.required && !value\n ? `${field.label} must be checked.`\n : undefined\n\n if (field.type === 'number') {\n if (!Predicate.isNumber(value) || !Number.isFinite(value)) return 'Enter a number.'\n\n if (field.min !== undefined && value < field.min) return `Enter at least ${field.min}.`\n\n if (field.max !== undefined && value > field.max) return `Enter at most ${field.max}.`\n\n return undefined\n }\n\n if (!Predicate.isString(value)) return 'Enter text.'\n\n if (field.type === 'select' && !field.options.some((option) => option.id === value))\n return 'Choose an available option.'\n\n if (field.type === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/u.test(value)) return 'Enter a valid email address.'\n\n if (\n (field.type === 'text' || field.type === 'email' || field.type === 'textarea') &&\n field.minLength !== undefined &&\n value.length < field.minLength\n )\n return `Enter at least ${field.minLength} characters.`\n\n if (\n (field.type === 'text' || field.type === 'email' || field.type === 'textarea') &&\n field.maxLength !== undefined &&\n value.length > field.maxLength\n )\n return `Enter at most ${field.maxLength} characters.`\n\n return undefined\n}\n\ninterface DraftFormField {\n readonly id: string\n readonly label: string\n readonly type: FormFieldType\n readonly help?: string\n readonly required?: boolean\n readonly minLength?: number\n readonly maxLength?: number\n readonly min?: number\n readonly max?: number\n readonly options?: ReadonlyArray<FormOption>\n}\n\nconst DraftFormField: Schema.Codec<DraftFormField> = Schema.Struct({\n id: Schema.NonEmptyString,\n label: Schema.NonEmptyString,\n type: FormFieldTypeSchema,\n help: Schema.optionalKey(Schema.String),\n required: Schema.optionalKey(Schema.Boolean),\n minLength: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n maxLength: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n min: Schema.optionalKey(Schema.Finite),\n max: Schema.optionalKey(Schema.Finite),\n options: Schema.optionalKey(Schema.Array(FormOptionSchema)),\n})\n\nconst DraftFormSteps = Schema.Array(\n Schema.Struct({\n id: Schema.NonEmptyString,\n title: Schema.NonEmptyString,\n fields: Schema.Array(DraftFormField).check(Schema.isMinLength(1), Schema.isMaxLength(100)),\n }),\n).check(Schema.isMinLength(1), Schema.isMaxLength(20))\n\n/** Paths refer to authored nodes, never rendered Vue children. Revision comparison is exact. */\nexport function documentForms(\n document: { readonly id: FormDefinition['documentId']; readonly body: CmsMarkdownDocument },\n components: ReadonlyArray<ComponentDefinition>,\n preview = false,\n): FormDefinition[] {\n const forms: FormDefinition[] = []\n\n const visit = (nodes: CmsMarkdownDocument['nodes'], parent: number[], renderData: NodeRenderData) => {\n nodes.forEach((node, index) => {\n if (Predicate.isString(node) || node[0] === null) return\n const nodePath = [...parent, index]\n const projection = projectCmsEditorComponentAttributes(node[1], renderData)\n const capabilities = components.find((component) => component.name === node[0])?.authoring.form\n\n if (capabilities) {\n const parsed = parseFormSteps(projection.props.steps, capabilities, node[0])\n\n if (Result.isSuccess(parsed))\n forms.push({\n name: node[0],\n documentId: document.id,\n nodePath,\n steps: parsed.success,\n preview,\n revision: formRevision(node[0], capabilities, parsed.success),\n })\n }\n\n visit(node.slice(2).filter(isNode), nodePath, projection.renderData)\n })\n }\n\n visit(document.body.nodes, [], createCmsComarkRenderData(document.body))\n\n return forms\n}\n\nfunction formRevision(\n name: string,\n capabilities: FormCapabilities,\n steps: Schema.Schema.Type<typeof DraftFormSteps>,\n): string {\n return JSON.stringify([name, capabilities, steps])\n}\n\nfunction isNode(value: Schema.Json | undefined): value is CmsMarkdownDocument['nodes'][number] {\n return Predicate.isString(value) || Array.isArray(value)\n}\n\nexport function formAuthoring(capabilities: FormCapabilities): BlockAuthoring {\n const prop = (\n name: string,\n label: string,\n type: StructuredField['type'],\n input: StructuredField['input'],\n extra: Partial<StructuredField> = {},\n ): StructuredField => ({ name, label, type, input, required: false, nullable: false, options: [], ...extra })\n\n const question = [\n prop('label', 'Question', 'string', 'text', { required: true, defaultValue: 'New question' }),\n prop('type', 'Answer type', 'string', 'select', {\n required: true,\n defaultValue: capabilities.fieldTypes[0],\n options: capabilities.fieldTypes.map((value) => ({ value, label: value })),\n }),\n prop('help', 'Help text', 'string', 'textarea'),\n ...capabilities.rules.map((rule) =>\n prop(\n rule,\n {\n required: 'Required',\n minLength: 'Minimum characters',\n maxLength: 'Maximum characters',\n min: 'Minimum value',\n max: 'Maximum value',\n }[rule],\n rule === 'required' ? 'boolean' : 'number',\n rule === 'required' ? 'toggle' : 'number',\n ),\n ),\n prop('options', 'Choices', 'array', 'list', {\n fields: [prop('label', 'Choice', 'string', 'text', { required: true, defaultValue: 'New choice' })],\n }),\n ]\n\n return {\n version: 1,\n label: capabilities.label,\n group: 'Forms',\n form: capabilities,\n props: [\n prop('steps', 'Steps', 'array', 'list', {\n required: true,\n fields: [\n prop('title', 'Step title', 'string', 'text', { required: true, defaultValue: 'New step' }),\n prop('fields', 'Questions', 'array', 'list', { required: true, fields: question }),\n ],\n }),\n ],\n slots: [],\n initialProps: {\n steps: [\n {\n id: 'first-step',\n title: 'Your details',\n fields: [\n {\n id: 'first-question',\n label: 'Your answer',\n type: capabilities.fieldTypes[0] ?? 'text',\n ...(capabilities.fieldTypes[0] === 'select'\n ? { options: [{ id: 'first-choice', label: 'First choice' }] }\n : undefined),\n },\n ],\n },\n ],\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as DocumentId } from "./scalars-
|
|
1
|
+
import { r as DocumentId } from "./scalars-CVZqT3L0.js";
|
|
2
2
|
import { Schema } from "effect";
|
|
3
3
|
|
|
4
4
|
//#region ../protocol/src/Forms.ts
|
|
@@ -107,4 +107,4 @@ const FormResult = Schema.Union([
|
|
|
107
107
|
|
|
108
108
|
//#endregion
|
|
109
109
|
export { FormOption as a, FormSubmission as c, FormFieldType as i, FORM_SUBMISSION_MAX_BYTES as n, FormResult as o, FormCapabilities as r, FormSteps as s, FORM_REVISION_MAX_BYTES as t };
|
|
110
|
-
//# sourceMappingURL=Forms-
|
|
110
|
+
//# sourceMappingURL=Forms-CfNPTiCr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Forms-
|
|
1
|
+
{"version":3,"file":"Forms-CfNPTiCr.js","names":[],"sources":["../../../../protocol/src/Forms.ts"],"sourcesContent":["import { Schema } from 'effect'\nimport { DocumentId } from './internal/documents/scalars'\n\nexport const FORM_SUBMISSION_MAX_BYTES = 128 * 1024\n\n/** Budget for the JSON-escaped revision, leaving space for the envelope and answers. */\nexport const FORM_REVISION_MAX_BYTES = 60000\n\nexport type FormFieldType = 'text' | 'email' | 'textarea' | 'number' | 'checkbox' | 'select'\n\nexport const FormFieldType: Schema.Codec<FormFieldType> = Schema.Literals([\n 'text',\n 'email',\n 'textarea',\n 'number',\n 'checkbox',\n 'select',\n])\n\nexport type FormRule = 'required' | 'minLength' | 'maxLength' | 'min' | 'max'\n\nexport const FormRule: Schema.Codec<FormRule> = Schema.Literals(['required', 'minLength', 'maxLength', 'min', 'max'])\n\nexport interface FormCapabilities {\n readonly label: string\n readonly fieldTypes: ReadonlyArray<FormFieldType>\n readonly rules: ReadonlyArray<FormRule>\n}\n\nexport const FormCapabilities: Schema.Codec<FormCapabilities> = Schema.Struct({\n label: Schema.NonEmptyString,\n fieldTypes: Schema.Array(FormFieldType).check(Schema.isMinLength(1)),\n rules: Schema.Array(FormRule),\n})\n\nexport interface FormOption {\n readonly id: string\n readonly label: string\n}\n\nexport const FormOption: Schema.Codec<FormOption> = Schema.Struct({\n id: Schema.NonEmptyString,\n label: Schema.NonEmptyString,\n})\n\ninterface FormFieldBase {\n readonly id: string\n readonly label: string\n readonly help?: string\n readonly required?: boolean\n}\n\ninterface FormTextField<Type extends 'text' | 'email' | 'textarea'> extends FormFieldBase {\n readonly type: Type\n readonly minLength?: number\n readonly maxLength?: number\n}\n\nexport interface FormNumberField extends FormFieldBase {\n readonly type: 'number'\n readonly min?: number\n readonly max?: number\n}\n\nexport interface FormCheckboxField extends FormFieldBase {\n readonly type: 'checkbox'\n}\n\nexport interface FormSelectField extends FormFieldBase {\n readonly type: 'select'\n readonly options: readonly [FormOption, ...FormOption[]]\n}\n\nexport type FormField =\n | FormTextField<'text'>\n | FormTextField<'email'>\n | FormTextField<'textarea'>\n | FormNumberField\n | FormCheckboxField\n | FormSelectField\n\nconst formFieldBase = {\n id: Schema.NonEmptyString,\n label: Schema.NonEmptyString,\n help: Schema.optionalKey(Schema.String),\n required: Schema.optionalKey(Schema.Boolean),\n}\n\nconst formTextField = <Type extends 'text' | 'email' | 'textarea'>(type: Type) =>\n Schema.Struct({\n ...formFieldBase,\n type: Schema.Literals([type]),\n minLength: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n maxLength: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n })\n\nconst FormNumberField = Schema.Struct({\n ...formFieldBase,\n type: Schema.Literals(['number']),\n min: Schema.optionalKey(Schema.Finite),\n max: Schema.optionalKey(Schema.Finite),\n})\n\nconst FormCheckboxField = Schema.Struct({ ...formFieldBase, type: Schema.Literals(['checkbox']) })\n\nconst FormSelectField = Schema.Struct({\n ...formFieldBase,\n type: Schema.Literals(['select']),\n options: Schema.NonEmptyArray(FormOption),\n})\n\nexport const FormField: Schema.Codec<FormField> = Schema.Union([\n formTextField('text'),\n formTextField('email'),\n formTextField('textarea'),\n FormNumberField,\n FormCheckboxField,\n FormSelectField,\n])\n\nexport interface FormStep {\n readonly id: string\n readonly title: string\n readonly fields: ReadonlyArray<FormField>\n}\n\nexport const FormStep: Schema.Codec<FormStep> = Schema.Struct({\n id: Schema.NonEmptyString,\n title: Schema.NonEmptyString,\n fields: Schema.Array(FormField).check(Schema.isMinLength(1), Schema.isMaxLength(100)),\n})\n\nexport const FormSteps: Schema.Codec<ReadonlyArray<FormStep>> = Schema.Array(FormStep).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(20),\n)\n\nexport interface FormReference {\n readonly documentId: DocumentId\n readonly nodePath: ReadonlyArray<number>\n readonly revision: string\n}\n\nconst referenceFields = {\n documentId: DocumentId,\n nodePath: Schema.Array(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(64),\n ),\n revision: Schema.String.check(Schema.isMaxLength(FORM_REVISION_MAX_BYTES)),\n}\n\nexport const FormReference: Schema.Codec<\n FormReference,\n { readonly documentId: string; readonly nodePath: ReadonlyArray<number>; readonly revision: string }\n> = Schema.Struct(referenceFields)\n\nexport interface FormDefinition extends FormReference {\n readonly name: string\n readonly steps: ReadonlyArray<FormStep>\n readonly preview: boolean\n}\n\nexport type FormValues = Readonly<Record<string, string | number | boolean | null>>\n\nexport const FormValues: Schema.Codec<FormValues> = Schema.Record(\n Schema.String,\n Schema.Union([Schema.String, Schema.Finite, Schema.Boolean, Schema.Null]),\n)\n\nexport interface FormSubmission extends FormReference {\n readonly values: FormValues\n}\n\nexport const FormSubmission: Schema.Codec<\n FormSubmission,\n {\n readonly documentId: string\n readonly nodePath: ReadonlyArray<number>\n readonly revision: string\n readonly values: FormValues\n }\n> = Schema.Struct({ ...referenceFields, values: FormValues })\n\nconst AcceptedFormResult = Schema.Struct({\n status: Schema.Literals(['accepted']),\n reference: Schema.optionalKey(Schema.NonEmptyString),\n})\n\nconst InvalidFormResult = Schema.Struct({\n status: Schema.Literals(['invalid']),\n errors: Schema.Record(Schema.String, Schema.String),\n})\n\nconst StaleFormResult = Schema.Struct({ status: Schema.Literals(['stale']) })\n\nconst UnavailableFormResult = Schema.Struct({ status: Schema.Literals(['unavailable']) })\n\nconst FailedFormResult = Schema.Struct({ status: Schema.Literals(['failed']) })\n\nexport const FormResult = Schema.Union([\n AcceptedFormResult,\n InvalidFormResult,\n StaleFormResult,\n UnavailableFormResult,\n FailedFormResult,\n])\n\nexport type FormResult = typeof FormResult.Type\n"],"mappings":";;;;AAGA,MAAa,4BAA4B;;AAGzC,MAAa,0BAA0B;AAIvC,MAAa,gBAA6C,OAAO,SAAS;CACxE;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAID,MAAa,WAAmC,OAAO,SAAS;CAAC;CAAY;CAAa;CAAa;CAAO;AAAK,CAAC;AAQpH,MAAa,mBAAmD,OAAO,OAAO;CAC5E,OAAO,OAAO;CACd,YAAY,OAAO,MAAM,aAAa,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;CACnE,OAAO,OAAO,MAAM,QAAQ;AAC9B,CAAC;AAOD,MAAa,aAAuC,OAAO,OAAO;CAChE,IAAI,OAAO;CACX,OAAO,OAAO;AAChB,CAAC;AAsCD,MAAM,gBAAgB;CACpB,IAAI,OAAO;CACX,OAAO,OAAO;CACd,MAAM,OAAO,YAAY,OAAO,MAAM;CACtC,UAAU,OAAO,YAAY,OAAO,OAAO;AAC7C;AAEA,MAAM,iBAA6D,SACjE,OAAO,OAAO;CACZ,GAAG;CACH,MAAM,OAAO,SAAS,CAAC,IAAI,CAAC;CAC5B,WAAW,OAAO,YAAY,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC,CAAC;CAChF,WAAW,OAAO,YAAY,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC,CAAC;AAClF,CAAC;AAEH,MAAM,kBAAkB,OAAO,OAAO;CACpC,GAAG;CACH,MAAM,OAAO,SAAS,CAAC,QAAQ,CAAC;CAChC,KAAK,OAAO,YAAY,OAAO,MAAM;CACrC,KAAK,OAAO,YAAY,OAAO,MAAM;AACvC,CAAC;AAED,MAAM,oBAAoB,OAAO,OAAO;CAAE,GAAG;CAAe,MAAM,OAAO,SAAS,CAAC,UAAU,CAAC;AAAE,CAAC;AAEjG,MAAM,kBAAkB,OAAO,OAAO;CACpC,GAAG;CACH,MAAM,OAAO,SAAS,CAAC,QAAQ,CAAC;CAChC,SAAS,OAAO,cAAc,UAAU;AAC1C,CAAC;AAED,MAAa,YAAqC,OAAO,MAAM;CAC7D,cAAc,MAAM;CACpB,cAAc,OAAO;CACrB,cAAc,UAAU;CACxB;CACA;CACA;AACF,CAAC;AAQD,MAAa,WAAmC,OAAO,OAAO;CAC5D,IAAI,OAAO;CACX,OAAO,OAAO;CACd,QAAQ,OAAO,MAAM,SAAS,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,GAAG,CAAC;AACtF,CAAC;AAED,MAAa,YAAmD,OAAO,MAAM,QAAQ,CAAC,CAAC,MACrF,OAAO,YAAY,CAAC,GACpB,OAAO,YAAY,EAAE,CACvB;AAQA,MAAM,kBAAkB;CACtB,YAAY;CACZ,UAAU,OAAO,MAAM,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,MACzE,OAAO,YAAY,CAAC,GACpB,OAAO,YAAY,EAAE,CACvB;CACA,UAAU,OAAO,OAAO,MAAM,OAAO,YAAY,uBAAuB,CAAC;AAC3E;AAEA,MAAa,gBAGT,OAAO,OAAO,eAAe;AAUjC,MAAa,aAAuC,OAAO,OACzD,OAAO,QACP,OAAO,MAAM;CAAC,OAAO;CAAQ,OAAO;CAAQ,OAAO;CAAS,OAAO;AAAI,CAAC,CAC1E;AAMA,MAAa,iBAQT,OAAO,OAAO;CAAE,GAAG;CAAiB,QAAQ;AAAW,CAAC;AAE5D,MAAM,qBAAqB,OAAO,OAAO;CACvC,QAAQ,OAAO,SAAS,CAAC,UAAU,CAAC;CACpC,WAAW,OAAO,YAAY,OAAO,cAAc;AACrD,CAAC;AAED,MAAM,oBAAoB,OAAO,OAAO;CACtC,QAAQ,OAAO,SAAS,CAAC,SAAS,CAAC;CACnC,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM;AACpD,CAAC;AAED,MAAM,kBAAkB,OAAO,OAAO,EAAE,QAAQ,OAAO,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;AAE5E,MAAM,wBAAwB,OAAO,OAAO,EAAE,QAAQ,OAAO,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;AAExF,MAAM,mBAAmB,OAAO,OAAO,EAAE,QAAQ,OAAO,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;AAE9E,MAAa,aAAa,OAAO,MAAM;CACrC;CACA;CACA;CACA;CACA;AACF,CAAC"}
|