@phtngyn/cms 0.1.0-beta.0 → 0.1.0-beta.1
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 +72 -1
- package/package.json +5 -5
- package/src/Authoring.d.ts +13 -1
- package/src/{AuthoringSchema-BQ5kbhVB.js → Configuration-DyKo0sLS.js} +595 -367
- package/src/Configuration-DyKo0sLS.js.map +1 -0
- package/src/{DocumentEngine-Da0kWotL.js → DocumentEngine-DYObwMDY.js} +44 -66
- package/src/DocumentEngine-DYObwMDY.js.map +1 -0
- package/src/DocumentModel.d.ts +4 -0
- package/src/DocumentModel.js.map +1 -1
- package/src/{HttpPaths-86qLGB90.js → HttpPaths-BbS21Jy8.js} +4 -2
- package/src/{HttpPaths-86qLGB90.js.map → HttpPaths-BbS21Jy8.js.map} +1 -1
- package/src/Module.js +27 -76
- package/src/Module.js.map +1 -1
- package/src/{StudioHttp-BTLLooh0.js → StudioHttp-jR2-bc01.js} +44 -242
- package/src/StudioHttp-jR2-bc01.js.map +1 -0
- package/src/{connection-ZGtL54qY.js → connection-CBTY-TzB.js} +3 -3
- package/src/{connection-ZGtL54qY.js.map → connection-CBTY-TzB.js.map} +1 -1
- package/src/{installation-BNKaVjni.js → installation-DeuBiFRE.js} +488 -236
- package/src/installation-DeuBiFRE.js.map +1 -0
- package/src/internal/authoring-catalog.js +147 -0
- package/src/internal/authoring-catalog.js.map +1 -0
- package/src/internal/authoring-compiler.js +2 -1
- package/src/internal/authoring-compiler.js.map +1 -1
- package/src/internal/authoring-metadata.js +67 -48
- package/src/internal/authoring-metadata.js.map +1 -1
- package/src/internal/configuration.js +5 -6
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/document-model.js +3 -2
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/studio-app.js +66 -0
- package/src/internal/studio-app.js.map +1 -0
- package/src/location-DtYv2aes.js +36 -0
- package/src/location-DtYv2aes.js.map +1 -0
- package/src/{metadata-Czvi3E4K.js → metadata-DE1Mc2td.js} +2 -2
- package/src/{metadata-Czvi3E4K.js.map → metadata-DE1Mc2td.js.map} +1 -1
- package/src/{models-Citx8jBi.js → models-BkMgeaOL.js} +252 -3
- package/src/models-BkMgeaOL.js.map +1 -0
- package/src/{models-DS5ClMsH.js → models-C3witQBK.js} +8 -31
- package/src/models-C3witQBK.js.map +1 -0
- package/src/runtime/blocks.js +17 -0
- package/src/runtime/blocks.js.map +1 -0
- package/src/runtime/collaboration.js +9 -4
- package/src/runtime/collaboration.js.map +1 -1
- package/src/runtime/delivery/DocumentRenderer.js +6 -3
- package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
- package/src/runtime/delivery/blocks.js +6 -0
- package/src/runtime/delivery/blocks.js.map +1 -0
- package/src/runtime/delivery/context.js +12 -0
- package/src/runtime/delivery/context.js.map +1 -0
- package/src/runtime/delivery/document-page.js +5 -3
- package/src/runtime/delivery/document-page.js.map +1 -1
- package/src/runtime/delivery/document.js +18 -2
- package/src/runtime/delivery/document.js.map +1 -1
- package/src/runtime/delivery/error.js +11 -0
- package/src/runtime/delivery/error.js.map +1 -0
- package/src/runtime/delivery/plugin.js +21 -0
- package/src/runtime/delivery/plugin.js.map +1 -0
- package/src/runtime/delivery/useDocument.js +6 -3
- package/src/runtime/delivery/useDocument.js.map +1 -1
- package/src/runtime/delivery/useDocumentQuery.js +6 -3
- package/src/runtime/delivery/useDocumentQuery.js.map +1 -1
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +3 -3
- package/src/runtime/plugin.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +29 -10
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/overlay.js +65 -0
- package/src/runtime/preview/overlay.js.map +1 -0
- package/src/runtime/preview/plugin.client.js +21 -34
- package/src/runtime/preview/plugin.client.js.map +1 -1
- package/src/runtime/preview/preview.css +72 -4
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/studio-app.js +5 -1
- package/src/runtime/studio-app.js.map +1 -1
- package/src/runtime/studio-entry.js +36 -0
- package/src/runtime/studio-entry.js.map +1 -0
- package/src/runtime/studio-navigation.js +11 -0
- package/src/runtime/studio-navigation.js.map +1 -0
- package/src/{store-Nl4uxEXx.js → store-CfFFx9Ua.js} +3 -3
- package/src/{store-Nl4uxEXx.js.map → store-CfFFx9Ua.js.map} +1 -1
- package/studio/CreateDocumentDialog--L9lTfx6.js +256 -0
- package/studio/collaboration-DUuu678R.js +4565 -0
- package/studio/documentPlanning-BXX04Woe.js +28989 -0
- package/studio/dom-to-image-more.min-D6jGGdrW.js +877 -0
- package/studio/editor-PexnXkJY.js +30817 -0
- package/studio/host.css +3 -0
- package/studio/host.js +44179 -0
- package/studio/rolldown-runtime-B0aSnxlc.js +20 -0
- package/dist/studio/assets/ActivityEntryRow-D--fRvWI.js +0 -1
- package/dist/studio/assets/ActivityView-D-XBBUHb.js +0 -1
- package/dist/studio/assets/CreateDocumentDialog-CH8UH1QM.js +0 -1
- package/dist/studio/assets/DocumentsView-CxRpmAxt.js +0 -34
- package/dist/studio/assets/DropdownMenu-BSb1l7fr.js +0 -1
- package/dist/studio/assets/Input-DVao38h7.js +0 -3
- package/dist/studio/assets/MediaView-BHrPIjxB.js +0 -1
- package/dist/studio/assets/Modal-VNrXGa5C.js +0 -1
- package/dist/studio/assets/OverviewView-DfP6-mLZ.js +0 -1
- package/dist/studio/assets/Select-BJZIs9sY.js +0 -1
- package/dist/studio/assets/SettingsView-CerHe-ua.js +0 -1
- package/dist/studio/assets/Skeleton-CWJNi3nS.js +0 -1
- package/dist/studio/assets/StudioPageHeader-DP9HDAF2.js +0 -1
- package/dist/studio/assets/UsersView-cP3REkH2.js +0 -1
- package/dist/studio/assets/collaboration-BLnCzfvV.js +0 -4
- package/dist/studio/assets/context-dY4fNbn3.js +0 -1
- package/dist/studio/assets/editor-CE07wW83.js +0 -137
- package/dist/studio/assets/gateway-BAyQgCse.js +0 -10
- package/dist/studio/assets/index-CjoaPLhZ.js +0 -28
- package/dist/studio/assets/index-s2rPqCmP.css +0 -2
- package/dist/studio/assets/render-BkxbK2St.js +0 -83
- package/dist/studio/assets/rolldown-runtime-DK3Fl9T5.js +0 -1
- package/dist/studio/assets/useMediaLibrary-D7qR7aBf.js +0 -1
- package/dist/studio/index.html +0 -76
- package/src/AuthoringSchema-BQ5kbhVB.js.map +0 -1
- package/src/Configuration-BGYFD2N1.js +0 -150
- package/src/Configuration-BGYFD2N1.js.map +0 -1
- package/src/DocumentEngine-Da0kWotL.js.map +0 -1
- package/src/StudioHttp-BTLLooh0.js.map +0 -1
- package/src/installation-BNKaVjni.js.map +0 -1
- package/src/internal/component-metadata.js +0 -37
- package/src/internal/component-metadata.js.map +0 -1
- package/src/models-Citx8jBi.js.map +0 -1
- package/src/models-DS5ClMsH.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-model.js","names":[],"sources":["../../../../src/internal/document-model.ts"],"sourcesContent":["import type {\n DocumentSchemaProjection,\n ExecutableDocumentModel,\n ExecutableDocumentSchema,\n} from '@internal/document/DocumentEngine'\nimport type {\n DocumentConfiguration as DocumentConfigurationType,\n DocumentField,\n} from '@internal/protocol/Configuration'\nimport type { CmsCollectionOptions, CmsDocumentModelOptions, CmsFieldInput } from '../DocumentModel'\nimport { createDocumentEngine } from '@internal/document/DocumentEngine'\nimport { DocumentConfiguration } from '@internal/protocol/Configuration'\nimport { Effect, Result, Schema } from 'effect'\nimport { z } from 'zod'\nimport { FIELD_INPUT_METADATA } from './field-metadata'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\ntype EncodedDocumentConfiguration = Schema.Codec.Encoded<typeof DocumentConfiguration>\n\ninterface CmsDocumentModel {\n readonly authoring: DocumentConfigurationType\n readonly executable: ExecutableDocumentModel\n}\n\ninterface CompiledCollection {\n readonly authoring: EncodedDocumentConfiguration['types'][number]\n readonly executable: ExecutableDocumentSchema\n}\n\nexport class CmsDocumentModelInvalid extends Schema.TaggedError<CmsDocumentModelInvalid>()('Cms.DocumentModelInvalid', {\n message: Schema.NonEmptyString,\n path: Schema.NonEmptyString,\n}) {}\nconst isCmsDocumentModelInvalid = Schema.is(CmsDocumentModelInvalid)\n\n/** Compiles authored Zod schemas into the portable and server-only halves of the CMS document model. */\nexport function compileCmsDocumentModel(documents: CmsDocumentModelOptions): CmsDocumentModel {\n try {\n const compiled = Object.entries(documents.collections).map(([collection, options]) =>\n compileCollection(collection, options),\n )\n const decoded = Schema.decodeResult(DocumentConfiguration)({\n ...(documents.locales === undefined\n ? undefined\n : {\n locales: {\n ...documents.locales,\n fallbackLocale: documents.locales.fallbackLocale ?? null,\n locales: [...documents.locales.locales],\n prefixDefaultLocale: documents.locales.prefixDefaultLocale ?? false,\n },\n }),\n types: compiled.map((entry) => entry.authoring),\n })\n if (Result.isFailure(decoded)) throw invalid('documents', String(decoded.failure))\n const model = {\n authoring: decoded.success,\n executable: {\n types: Object.fromEntries(compiled.map((entry) => [entry.authoring.collection, entry.executable])),\n },\n }\n const engine = Effect.runSync(\n Effect.result(createDocumentEngine(model.authoring, { documentModel: model.executable })),\n )\n if (Result.isFailure(engine)) throw invalid('documents', engine.failure.message)\n return model\n } catch (cause) {\n throw isCmsDocumentModelInvalid(cause)\n ? cause\n : invalid('documents.collections', cause instanceof Error ? cause.message : String(cause))\n }\n}\n\nfunction compileCollection(collection: string, options: CmsCollectionOptions): CompiledCollection {\n const path = `documents.collections.${collection}`\n let generated: unknown\n try {\n generated = z.toJSONSchema(options.schema, {\n cycles: 'throw',\n io: 'input',\n reused: 'inline',\n target: 'draft-2020-12',\n unrepresentable: 'throw',\n })\n } catch (cause) {\n throw invalid(`${path}.schema`, cause instanceof Error ? cause.message : String(cause))\n }\n\n const decoded = Schema.decodeUnknownResult(Schema.JsonObject)(generated)\n if (Result.isFailure(decoded)) throw invalid(`${path}.schema`, 'The generated input structure is not serializable.')\n const input = decoded.success\n if (input.type !== 'object') throw invalid(`${path}.schema`, 'A collection schema must be a Zod object.')\n const projection = compileProjection(input, `${path}.schema`)\n\n return {\n authoring: {\n addressPattern: options.route,\n authoringFields: compileAuthoringFields(input, `${path}.schema`),\n canCreate: options.canCreate ?? true,\n collection,\n description: options.description ?? '',\n directory: options.source ?? collection,\n hierarchy: options.hierarchy ?? options.route.includes('*'),\n label: options.label,\n },\n executable: {\n project: projection,\n validate: (value) => Effect.tryPromise(() => Promise.resolve(options.schema['~standard'].validate(value))),\n },\n }\n}\n\ntype ProjectDocumentProjection = (input: Schema.JsonObject) => DocumentSchemaProjection\n\nfunction compileProjection(schema: Schema.JsonObject, path: string, parent = ''): ProjectDocumentProjection {\n const properties = objectKeyword(schema, 'properties', path, true)\n const declarations = new Map(\n Object.entries(properties).map(([name, value]) => {\n const fieldPath = parent ? `${parent}.${name}` : name\n const property = requireObject(value, `${path}.${name}`)\n const nested = property.type === 'object' ? compileProjection(property, `${path}.${name}`, fieldPath) : undefined\n return [name, nested] as const\n }),\n )\n return (input) => {\n const value: Record<string, Schema.Json> = {}\n const unknownPaths: string[] = []\n for (const [name, child] of Object.entries(input)) {\n const nested = declarations.get(name)\n if (!declarations.has(name)) {\n unknownPaths.push(parent ? `${parent}.${name}` : name)\n } else if (nested && isJsonObject(child)) {\n const projected = nested(child)\n value[name] = projected.value\n unknownPaths.push(...projected.unknownPaths)\n } else {\n value[name] = child\n }\n }\n return { unknownPaths, value }\n }\n}\n\nfunction compileAuthoringFields(\n schema: Schema.JsonObject,\n path: string,\n parent = '',\n parentRequired = true,\n): ReadonlyArray<DocumentField> {\n const properties = objectKeyword(schema, 'properties', path, true)\n const required = stringArrayKeyword(schema, 'required', path)\n return Object.entries(properties).flatMap(([name, value]) => {\n if (!name || name.includes('.')) {\n throw invalid(`${path}.${name || '<empty>'}`, 'Field names must be non-empty and cannot contain dots.')\n }\n const fieldPath = parent ? `${parent}.${name}` : name\n if (fieldPath === 'id') throw invalid(`${path}.id`, 'Field \"id\" is reserved for CMS identity.')\n const property = requireObject(value, `${path}.${name}`)\n const fieldRequired = parentRequired && required.has(name)\n if (property.type === 'object') {\n if (property.default !== undefined) {\n throw invalid(\n `${path}.${name}`,\n 'Defaults on object fields are not supported; default their leaf fields instead.',\n )\n }\n return compileAuthoringFields(property, `${path}.${name}`, fieldPath, fieldRequired)\n }\n return [compileAuthoringField(property, `${path}.${name}`, fieldPath, fieldRequired)]\n })\n}\n\nfunction compileAuthoringField(\n schema: Schema.JsonObject,\n schemaPath: string,\n path: string,\n required: boolean,\n): DocumentField {\n const presentation = fieldPresentation(schema, schemaPath, path, required)\n switch (schema.type) {\n case 'boolean':\n return { ...presentation, input: input(schema, schemaPath, 'toggle', ['toggle']), type: 'boolean' }\n case 'integer':\n case 'number': {\n const options = numericOptions(schema.enum, schemaPath)\n return {\n ...presentation,\n input: input(schema, schemaPath, options.length > 0 ? 'select' : 'number', ['number', 'select']),\n options,\n type: 'number',\n }\n }\n case 'string': {\n if (schema.format === 'date') {\n return { ...presentation, input: input(schema, schemaPath, 'date', ['date']), type: 'date' }\n }\n const options = stringOptions(schema.enum, schemaPath)\n return {\n ...presentation,\n input: input(schema, schemaPath, options.length > 0 ? 'select' : 'text', ['select', 'text', 'textarea']),\n options,\n type: 'string',\n }\n }\n case 'array': {\n const items = requireObject(schema.items, `${schemaPath}[]`)\n if (items.type !== 'string') throw invalid(schemaPath, 'Studio currently supports authoring arrays of strings.')\n return {\n ...presentation,\n input: input(schema, schemaPath, 'multiselect', ['multiselect']),\n options: stringOptions(items.enum, `${schemaPath}[]`),\n type: 'string[]',\n }\n }\n default:\n throw invalid(schemaPath, `Studio cannot generate an input for schema type \"${displayJson(schema.type)}\".`)\n }\n}\n\nfunction fieldPresentation(schema: Schema.JsonObject, schemaPath: string, path: string, required: boolean) {\n const defaultValue = schema.default\n const description = stringKeyword(schema, 'description', schemaPath)\n const title = stringKeyword(schema, 'title', schemaPath)\n return {\n ...(defaultValue === undefined ? undefined : { defaultValue }),\n ...(description === undefined ? undefined : { description }),\n label: title?.trim() || humanize(path),\n path,\n required,\n }\n}\n\nfunction input<const Supported extends ReadonlyArray<CmsFieldInput>>(\n schema: Schema.JsonObject,\n path: string,\n fallback: Supported[number],\n supported: Supported,\n): Supported[number] {\n const configured = schema[FIELD_INPUT_METADATA]\n if (configured === undefined) return fallback\n const decoded = Schema.decodeUnknownResult(Schema.Literals([...supported]))(configured)\n if (Result.isSuccess(decoded)) return decoded.success\n throw invalid(path, `Input \"${displayJson(configured)}\" is not compatible with this field.`)\n}\n\nfunction stringOptions(value: Schema.Json | undefined, path: string): ReadonlyArray<string> {\n if (value === undefined) return []\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.String))(value)\n if (Result.isFailure(decoded)) throw invalid(path, 'Field options must all be strings.')\n return decoded.success\n}\n\nfunction numericOptions(value: Schema.Json | undefined, path: string): ReadonlyArray<number> {\n if (value === undefined) return []\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.Finite))(value)\n if (Result.isFailure(decoded)) throw invalid(path, 'Field options must all be finite numbers.')\n return decoded.success\n}\n\nfunction objectKeyword(schema: Schema.JsonObject, keyword: string, path: string, optional = false): Schema.JsonObject {\n const value = schema[keyword]\n if (value === undefined && optional) return {}\n return requireObject(value, `${path}.${keyword}`)\n}\n\nfunction stringArrayKeyword(schema: Schema.JsonObject, keyword: string, path: string): ReadonlySet<string> {\n const value = schema[keyword]\n if (value === undefined) return new Set()\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.String))(value)\n if (Result.isFailure(decoded)) throw invalid(`${path}.${keyword}`, `Expected \"${keyword}\" to be an array of strings.`)\n return new Set(decoded.success)\n}\n\nfunction stringKeyword(schema: Schema.JsonObject, keyword: string, path: string): string | undefined {\n const value = schema[keyword]\n if (value === undefined) return undefined\n const decoded = Schema.decodeUnknownResult(Schema.String)(value)\n if (Result.isFailure(decoded)) throw invalid(`${path}.${keyword}`, `Expected \"${keyword}\" to be a string.`)\n return decoded.success\n}\n\nfunction requireObject(value: Schema.Json | undefined, path: string): Schema.JsonObject {\n if (!isJsonObject(value)) throw invalid(path, 'Studio requires an object input structure at this location.')\n return value\n}\n\nfunction humanize(path: string): string {\n const name = path.split('.').at(-1) ?? path\n const words = name\n .replace(/([a-z\\d])([A-Z])/gu, '$1 $2')\n .replace(/[-_]+/gu, ' ')\n .trim()\n return words ? `${words.charAt(0).toUpperCase()}${words.slice(1)}` : name\n}\n\nfunction displayJson(value: Schema.Json | undefined): string {\n return value === undefined ? 'undefined' : (JSON.stringify(value) ?? 'undefined')\n}\n\nfunction invalid(path: string, message: string): CmsDocumentModelInvalid {\n return new CmsDocumentModelInvalid({ message, path })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-model.js","names":[],"sources":["../../../../src/internal/document-model.ts"],"sourcesContent":["import type {\n DocumentSchemaProjection,\n ExecutableDocumentModel,\n ExecutableDocumentSchema,\n} from '@internal/document/DocumentEngine'\nimport type {\n DocumentConfiguration as DocumentConfigurationType,\n DocumentField,\n} from '@internal/protocol/Configuration'\nimport type { CmsCollectionOptions, CmsDocumentModelOptions, CmsFieldInput } from '../DocumentModel'\nimport { createDocumentEngine } from '@internal/document/DocumentEngine'\nimport { DocumentConfiguration } from '@internal/protocol/Configuration'\nimport { Effect, Result, Schema } from 'effect'\nimport { z } from 'zod'\nimport { FIELD_INPUT_METADATA } from './field-metadata'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\ntype EncodedDocumentConfiguration = Schema.Codec.Encoded<typeof DocumentConfiguration>\n\ninterface CmsDocumentModel {\n readonly authoring: DocumentConfigurationType\n readonly executable: ExecutableDocumentModel\n}\n\ninterface CompiledCollection {\n readonly authoring: EncodedDocumentConfiguration['types'][number]\n readonly executable: ExecutableDocumentSchema\n}\n\nexport class CmsDocumentModelInvalid extends Schema.TaggedError<CmsDocumentModelInvalid>()('Cms.DocumentModelInvalid', {\n message: Schema.NonEmptyString,\n path: Schema.NonEmptyString,\n}) {}\nconst isCmsDocumentModelInvalid = Schema.is(CmsDocumentModelInvalid)\n\n/** Compiles authored Zod schemas into the portable and server-only halves of the CMS document model. */\nexport function compileCmsDocumentModel(documents: CmsDocumentModelOptions): CmsDocumentModel {\n try {\n const compiled = Object.entries(documents.collections).map(([collection, options]) =>\n compileCollection(collection, options),\n )\n const decoded = Schema.decodeResult(DocumentConfiguration)({\n ...(documents.locales === undefined\n ? undefined\n : {\n locales: {\n ...documents.locales,\n fallbackLocale: documents.locales.fallbackLocale ?? null,\n locales: [...documents.locales.locales],\n prefixDefaultLocale: documents.locales.prefixDefaultLocale ?? false,\n },\n }),\n types: compiled.map((entry) => entry.authoring),\n })\n if (Result.isFailure(decoded)) throw invalid('documents', String(decoded.failure))\n const model = {\n authoring: decoded.success,\n executable: {\n types: Object.fromEntries(compiled.map((entry) => [entry.authoring.collection, entry.executable])),\n },\n }\n const engine = Effect.runSync(\n Effect.result(createDocumentEngine(model.authoring, { documentModel: model.executable })),\n )\n if (Result.isFailure(engine)) throw invalid('documents', engine.failure.message)\n return model\n } catch (cause) {\n throw isCmsDocumentModelInvalid(cause)\n ? cause\n : invalid('documents.collections', cause instanceof Error ? cause.message : String(cause))\n }\n}\n\nfunction compileCollection(collection: string, options: CmsCollectionOptions): CompiledCollection {\n const path = `documents.collections.${collection}`\n let generated: unknown\n try {\n generated = z.toJSONSchema(options.schema, {\n cycles: 'throw',\n io: 'input',\n reused: 'inline',\n target: 'draft-2020-12',\n unrepresentable: 'throw',\n })\n } catch (cause) {\n throw invalid(`${path}.schema`, cause instanceof Error ? cause.message : String(cause))\n }\n\n const decoded = Schema.decodeUnknownResult(Schema.JsonObject)(generated)\n if (Result.isFailure(decoded)) throw invalid(`${path}.schema`, 'The generated input structure is not serializable.')\n const input = decoded.success\n if (input.type !== 'object') throw invalid(`${path}.schema`, 'A collection schema must be a Zod object.')\n const projection = compileProjection(input, `${path}.schema`)\n\n return {\n authoring: {\n addressPattern: options.route,\n ...(options.body === undefined ? undefined : { body: options.body }),\n authoringFields: compileAuthoringFields(input, `${path}.schema`),\n canCreate: options.canCreate ?? true,\n collection,\n description: options.description ?? '',\n directory: options.source ?? collection,\n hierarchy: options.hierarchy ?? options.route.includes('*'),\n label: options.label,\n },\n executable: {\n project: projection,\n validate: (value) => Effect.tryPromise(() => Promise.resolve(options.schema['~standard'].validate(value))),\n },\n }\n}\n\ntype ProjectDocumentProjection = (input: Schema.JsonObject) => DocumentSchemaProjection\n\nfunction compileProjection(schema: Schema.JsonObject, path: string, parent = ''): ProjectDocumentProjection {\n const properties = objectKeyword(schema, 'properties', path, true)\n const declarations = new Map(\n Object.entries(properties).map(([name, value]) => {\n const fieldPath = parent ? `${parent}.${name}` : name\n const property = requireObject(value, `${path}.${name}`)\n const nested = property.type === 'object' ? compileProjection(property, `${path}.${name}`, fieldPath) : undefined\n return [name, nested] as const\n }),\n )\n return (input) => {\n const value: Record<string, Schema.Json> = {}\n const unknownPaths: string[] = []\n for (const [name, child] of Object.entries(input)) {\n const nested = declarations.get(name)\n if (!declarations.has(name)) {\n unknownPaths.push(parent ? `${parent}.${name}` : name)\n } else if (nested && isJsonObject(child)) {\n const projected = nested(child)\n value[name] = projected.value\n unknownPaths.push(...projected.unknownPaths)\n } else {\n value[name] = child\n }\n }\n return { unknownPaths, value }\n }\n}\n\nfunction compileAuthoringFields(\n schema: Schema.JsonObject,\n path: string,\n parent = '',\n parentRequired = true,\n): ReadonlyArray<DocumentField> {\n const properties = objectKeyword(schema, 'properties', path, true)\n const required = stringArrayKeyword(schema, 'required', path)\n return Object.entries(properties).flatMap(([name, value]) => {\n if (!name || name.includes('.')) {\n throw invalid(`${path}.${name || '<empty>'}`, 'Field names must be non-empty and cannot contain dots.')\n }\n const fieldPath = parent ? `${parent}.${name}` : name\n if (fieldPath === 'id') throw invalid(`${path}.id`, 'Field \"id\" is reserved for CMS identity.')\n const property = requireObject(value, `${path}.${name}`)\n const fieldRequired = parentRequired && required.has(name)\n if (property.type === 'object') {\n if (property.default !== undefined) {\n throw invalid(\n `${path}.${name}`,\n 'Defaults on object fields are not supported; default their leaf fields instead.',\n )\n }\n return compileAuthoringFields(property, `${path}.${name}`, fieldPath, fieldRequired)\n }\n return [compileAuthoringField(property, `${path}.${name}`, fieldPath, fieldRequired)]\n })\n}\n\nfunction compileAuthoringField(\n schema: Schema.JsonObject,\n schemaPath: string,\n path: string,\n required: boolean,\n): DocumentField {\n const presentation = fieldPresentation(schema, schemaPath, path, required)\n switch (schema.type) {\n case 'boolean':\n return { ...presentation, input: input(schema, schemaPath, 'toggle', ['toggle']), type: 'boolean' }\n case 'integer':\n case 'number': {\n const options = numericOptions(schema.enum, schemaPath)\n return {\n ...presentation,\n input: input(schema, schemaPath, options.length > 0 ? 'select' : 'number', ['number', 'select']),\n options,\n type: 'number',\n }\n }\n case 'string': {\n if (schema.format === 'date') {\n return { ...presentation, input: input(schema, schemaPath, 'date', ['date']), type: 'date' }\n }\n const options = stringOptions(schema.enum, schemaPath)\n return {\n ...presentation,\n input: input(schema, schemaPath, options.length > 0 ? 'select' : 'text', ['select', 'text', 'textarea']),\n options,\n type: 'string',\n }\n }\n case 'array': {\n const items = requireObject(schema.items, `${schemaPath}[]`)\n if (items.type !== 'string') throw invalid(schemaPath, 'Studio currently supports authoring arrays of strings.')\n return {\n ...presentation,\n input: input(schema, schemaPath, 'multiselect', ['multiselect']),\n options: stringOptions(items.enum, `${schemaPath}[]`),\n type: 'string[]',\n }\n }\n default:\n throw invalid(schemaPath, `Studio cannot generate an input for schema type \"${displayJson(schema.type)}\".`)\n }\n}\n\nfunction fieldPresentation(schema: Schema.JsonObject, schemaPath: string, path: string, required: boolean) {\n const defaultValue = schema.default\n const description = stringKeyword(schema, 'description', schemaPath)\n const title = stringKeyword(schema, 'title', schemaPath)\n return {\n ...(defaultValue === undefined ? undefined : { defaultValue }),\n ...(description === undefined ? undefined : { description }),\n label: title?.trim() || humanize(path),\n path,\n required,\n }\n}\n\nfunction input<const Supported extends ReadonlyArray<CmsFieldInput>>(\n schema: Schema.JsonObject,\n path: string,\n fallback: Supported[number],\n supported: Supported,\n): Supported[number] {\n const configured = schema[FIELD_INPUT_METADATA]\n if (configured === undefined) return fallback\n const decoded = Schema.decodeUnknownResult(Schema.Literals([...supported]))(configured)\n if (Result.isSuccess(decoded)) return decoded.success\n throw invalid(path, `Input \"${displayJson(configured)}\" is not compatible with this field.`)\n}\n\nfunction stringOptions(value: Schema.Json | undefined, path: string): ReadonlyArray<string> {\n if (value === undefined) return []\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.String))(value)\n if (Result.isFailure(decoded)) throw invalid(path, 'Field options must all be strings.')\n return decoded.success\n}\n\nfunction numericOptions(value: Schema.Json | undefined, path: string): ReadonlyArray<number> {\n if (value === undefined) return []\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.Finite))(value)\n if (Result.isFailure(decoded)) throw invalid(path, 'Field options must all be finite numbers.')\n return decoded.success\n}\n\nfunction objectKeyword(schema: Schema.JsonObject, keyword: string, path: string, optional = false): Schema.JsonObject {\n const value = schema[keyword]\n if (value === undefined && optional) return {}\n return requireObject(value, `${path}.${keyword}`)\n}\n\nfunction stringArrayKeyword(schema: Schema.JsonObject, keyword: string, path: string): ReadonlySet<string> {\n const value = schema[keyword]\n if (value === undefined) return new Set()\n const decoded = Schema.decodeUnknownResult(Schema.Array(Schema.String))(value)\n if (Result.isFailure(decoded)) throw invalid(`${path}.${keyword}`, `Expected \"${keyword}\" to be an array of strings.`)\n return new Set(decoded.success)\n}\n\nfunction stringKeyword(schema: Schema.JsonObject, keyword: string, path: string): string | undefined {\n const value = schema[keyword]\n if (value === undefined) return undefined\n const decoded = Schema.decodeUnknownResult(Schema.String)(value)\n if (Result.isFailure(decoded)) throw invalid(`${path}.${keyword}`, `Expected \"${keyword}\" to be a string.`)\n return decoded.success\n}\n\nfunction requireObject(value: Schema.Json | undefined, path: string): Schema.JsonObject {\n if (!isJsonObject(value)) throw invalid(path, 'Studio requires an object input structure at this location.')\n return value\n}\n\nfunction humanize(path: string): string {\n const name = path.split('.').at(-1) ?? path\n const words = name\n .replace(/([a-z\\d])([A-Z])/gu, '$1 $2')\n .replace(/[-_]+/gu, ' ')\n .trim()\n return words ? `${words.charAt(0).toUpperCase()}${words.slice(1)}` : name\n}\n\nfunction displayJson(value: Schema.Json | undefined): string {\n return value === undefined ? 'undefined' : (JSON.stringify(value) ?? 'undefined')\n}\n\nfunction invalid(path: string, message: string): CmsDocumentModelInvalid {\n return new CmsDocumentModelInvalid({ message, path })\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,eAAe,OAAO,GAAG,OAAO,UAAU;AAchD,IAAa,0BAAb,cAA6C,OAAO,YAAqC,CAAC,CAAC,4BAA4B;CACrH,SAAS,OAAO;CAChB,MAAM,OAAO;AACf,CAAC,CAAC,CAAC,CAAC;AACJ,MAAM,4BAA4B,OAAO,GAAG,uBAAuB;;AAGnE,SAAgB,wBAAwB,WAAsD;CAC5F,IAAI;EACF,MAAM,WAAW,OAAO,QAAQ,UAAU,WAAW,CAAC,CAAC,KAAK,CAAC,YAAY,aACvE,kBAAkB,YAAY,OAAO,CACvC;EACA,MAAM,UAAU,OAAO,aAAa,qBAAqB,CAAC,CAAC;GACzD,GAAI,UAAU,YAAY,SACtB,SACA,EACE,SAAS;IACP,GAAG,UAAU;IACb,gBAAgB,UAAU,QAAQ,kBAAkB;IACpD,SAAS,CAAC,GAAG,UAAU,QAAQ,OAAO;IACtC,qBAAqB,UAAU,QAAQ,uBAAuB;GAChE,EACF;GACJ,OAAO,SAAS,KAAK,UAAU,MAAM,SAAS;EAChD,CAAC;EACD,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,aAAa,OAAO,QAAQ,OAAO,CAAC;EACjF,MAAM,QAAQ;GACZ,WAAW,QAAQ;GACnB,YAAY,EACV,OAAO,OAAO,YAAY,SAAS,KAAK,UAAU,CAAC,MAAM,UAAU,YAAY,MAAM,UAAU,CAAC,CAAC,EACnG;EACF;EACA,MAAM,SAAS,OAAO,QACpB,OAAO,OAAO,qBAAqB,MAAM,WAAW,EAAE,eAAe,MAAM,WAAW,CAAC,CAAC,CAC1F;EACA,IAAI,OAAO,UAAU,MAAM,GAAG,MAAM,QAAQ,aAAa,OAAO,QAAQ,OAAO;EAC/E,OAAO;CACT,SAAS,OAAO;EACd,MAAM,0BAA0B,KAAK,IACjC,QACA,QAAQ,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CAC7F;AACF;AAEA,SAAS,kBAAkB,YAAoB,SAAmD;CAChG,MAAM,OAAO,yBAAyB;CACtC,IAAI;CACJ,IAAI;EACF,YAAY,EAAE,aAAa,QAAQ,QAAQ;GACzC,QAAQ;GACR,IAAI;GACJ,QAAQ;GACR,QAAQ;GACR,iBAAiB;EACnB,CAAC;CACH,SAAS,OAAO;EACd,MAAM,QAAQ,GAAG,KAAK,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CACxF;CAEA,MAAM,UAAU,OAAO,oBAAoB,OAAO,UAAU,CAAC,CAAC,SAAS;CACvE,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,GAAG,KAAK,UAAU,oDAAoD;CACnH,MAAM,QAAQ,QAAQ;CACtB,IAAI,MAAM,SAAS,UAAU,MAAM,QAAQ,GAAG,KAAK,UAAU,2CAA2C;CACxG,MAAM,aAAa,kBAAkB,OAAO,GAAG,KAAK,QAAQ;CAE5D,OAAO;EACL,WAAW;GACT,gBAAgB,QAAQ;GACxB,GAAI,QAAQ,SAAS,SAAY,SAAY,EAAE,MAAM,QAAQ,KAAK;GAClE,iBAAiB,uBAAuB,OAAO,GAAG,KAAK,QAAQ;GAC/D,WAAW,QAAQ,aAAa;GAChC;GACA,aAAa,QAAQ,eAAe;GACpC,WAAW,QAAQ,UAAU;GAC7B,WAAW,QAAQ,aAAa,QAAQ,MAAM,SAAS,GAAG;GAC1D,OAAO,QAAQ;EACjB;EACA,YAAY;GACV,SAAS;GACT,WAAW,UAAU,OAAO,iBAAiB,QAAQ,QAAQ,QAAQ,OAAO,YAAY,CAAC,SAAS,KAAK,CAAC,CAAC;EAC3G;CACF;AACF;AAIA,SAAS,kBAAkB,QAA2B,MAAc,SAAS,IAA+B;CAC1G,MAAM,aAAa,cAAc,QAAQ,cAAc,MAAM,IAAI;CACjE,MAAM,eAAe,IAAI,IACvB,OAAO,QAAQ,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW;EAChD,MAAM,YAAY,SAAS,GAAG,OAAO,GAAG,SAAS;EACjD,MAAM,WAAW,cAAc,OAAO,GAAG,KAAK,GAAG,MAAM;EAEvD,OAAO,CAAC,MADO,SAAS,SAAS,WAAW,kBAAkB,UAAU,GAAG,KAAK,GAAG,QAAQ,SAAS,IAAI,MACpF;CACtB,CAAC,CACH;CACA,QAAQ,UAAU;EAChB,MAAM,QAAqC,CAAC;EAC5C,MAAM,eAAyB,CAAC;EAChC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,GAAG;GACjD,MAAM,SAAS,aAAa,IAAI,IAAI;GACpC,IAAI,CAAC,aAAa,IAAI,IAAI,GACxB,aAAa,KAAK,SAAS,GAAG,OAAO,GAAG,SAAS,IAAI;QAChD,IAAI,UAAU,aAAa,KAAK,GAAG;IACxC,MAAM,YAAY,OAAO,KAAK;IAC9B,MAAM,QAAQ,UAAU;IACxB,aAAa,KAAK,GAAG,UAAU,YAAY;GAC7C,OACE,MAAM,QAAQ;EAElB;EACA,OAAO;GAAE;GAAc;EAAM;CAC/B;AACF;AAEA,SAAS,uBACP,QACA,MACA,SAAS,IACT,iBAAiB,MACa;CAC9B,MAAM,aAAa,cAAc,QAAQ,cAAc,MAAM,IAAI;CACjE,MAAM,WAAW,mBAAmB,QAAQ,YAAY,IAAI;CAC5D,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,WAAW;EAC3D,IAAI,CAAC,QAAQ,KAAK,SAAS,GAAG,GAC5B,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,aAAa,wDAAwD;EAExG,MAAM,YAAY,SAAS,GAAG,OAAO,GAAG,SAAS;EACjD,IAAI,cAAc,MAAM,MAAM,QAAQ,GAAG,KAAK,MAAM,4CAA0C;EAC9F,MAAM,WAAW,cAAc,OAAO,GAAG,KAAK,GAAG,MAAM;EACvD,MAAM,gBAAgB,kBAAkB,SAAS,IAAI,IAAI;EACzD,IAAI,SAAS,SAAS,UAAU;GAC9B,IAAI,SAAS,YAAY,QACvB,MAAM,QACJ,GAAG,KAAK,GAAG,QACX,iFACF;GAEF,OAAO,uBAAuB,UAAU,GAAG,KAAK,GAAG,QAAQ,WAAW,aAAa;EACrF;EACA,OAAO,CAAC,sBAAsB,UAAU,GAAG,KAAK,GAAG,QAAQ,WAAW,aAAa,CAAC;CACtF,CAAC;AACH;AAEA,SAAS,sBACP,QACA,YACA,MACA,UACe;CACf,MAAM,eAAe,kBAAkB,QAAQ,YAAY,MAAM,QAAQ;CACzE,QAAQ,OAAO,MAAf;EACE,KAAK,WACH,OAAO;GAAE,GAAG;GAAc,OAAO,MAAM,QAAQ,YAAY,UAAU,CAAC,QAAQ,CAAC;GAAG,MAAM;EAAU;EACpG,KAAK;EACL,KAAK,UAAU;GACb,MAAM,UAAU,eAAe,OAAO,MAAM,UAAU;GACtD,OAAO;IACL,GAAG;IACH,OAAO,MAAM,QAAQ,YAAY,QAAQ,SAAS,IAAI,WAAW,UAAU,CAAC,UAAU,QAAQ,CAAC;IAC/F;IACA,MAAM;GACR;EACF;EACA,KAAK,UAAU;GACb,IAAI,OAAO,WAAW,QACpB,OAAO;IAAE,GAAG;IAAc,OAAO,MAAM,QAAQ,YAAY,QAAQ,CAAC,MAAM,CAAC;IAAG,MAAM;GAAO;GAE7F,MAAM,UAAU,cAAc,OAAO,MAAM,UAAU;GACrD,OAAO;IACL,GAAG;IACH,OAAO,MAAM,QAAQ,YAAY,QAAQ,SAAS,IAAI,WAAW,QAAQ;KAAC;KAAU;KAAQ;IAAU,CAAC;IACvG;IACA,MAAM;GACR;EACF;EACA,KAAK,SAAS;GACZ,MAAM,QAAQ,cAAc,OAAO,OAAO,GAAG,WAAW,GAAG;GAC3D,IAAI,MAAM,SAAS,UAAU,MAAM,QAAQ,YAAY,wDAAwD;GAC/G,OAAO;IACL,GAAG;IACH,OAAO,MAAM,QAAQ,YAAY,eAAe,CAAC,aAAa,CAAC;IAC/D,SAAS,cAAc,MAAM,MAAM,GAAG,WAAW,GAAG;IACpD,MAAM;GACR;EACF;EACA,SACE,MAAM,QAAQ,YAAY,oDAAoD,YAAY,OAAO,IAAI,EAAE,GAAG;CAC9G;AACF;AAEA,SAAS,kBAAkB,QAA2B,YAAoB,MAAc,UAAmB;CACzG,MAAM,eAAe,OAAO;CAC5B,MAAM,cAAc,cAAc,QAAQ,eAAe,UAAU;CACnE,MAAM,QAAQ,cAAc,QAAQ,SAAS,UAAU;CACvD,OAAO;EACL,GAAI,iBAAiB,SAAY,SAAY,EAAE,aAAa;EAC5D,GAAI,gBAAgB,SAAY,SAAY,EAAE,YAAY;EAC1D,OAAO,OAAO,KAAK,KAAK,SAAS,IAAI;EACrC;EACA;CACF;AACF;AAEA,SAAS,MACP,QACA,MACA,UACA,WACmB;CACnB,MAAM,aAAa,OAAO;CAC1B,IAAI,eAAe,QAAW,OAAO;CACrC,MAAM,UAAU,OAAO,oBAAoB,OAAO,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU;CACtF,IAAI,OAAO,UAAU,OAAO,GAAG,OAAO,QAAQ;CAC9C,MAAM,QAAQ,MAAM,UAAU,YAAY,UAAU,EAAE,qCAAqC;AAC7F;AAEA,SAAS,cAAc,OAAgC,MAAqC;CAC1F,IAAI,UAAU,QAAW,OAAO,CAAC;CACjC,MAAM,UAAU,OAAO,oBAAoB,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK;CAC7E,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,MAAM,oCAAoC;CACvF,OAAO,QAAQ;AACjB;AAEA,SAAS,eAAe,OAAgC,MAAqC;CAC3F,IAAI,UAAU,QAAW,OAAO,CAAC;CACjC,MAAM,UAAU,OAAO,oBAAoB,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK;CAC7E,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,MAAM,2CAA2C;CAC9F,OAAO,QAAQ;AACjB;AAEA,SAAS,cAAc,QAA2B,SAAiB,MAAc,WAAW,OAA0B;CACpH,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,UAAa,UAAU,OAAO,CAAC;CAC7C,OAAO,cAAc,OAAO,GAAG,KAAK,GAAG,SAAS;AAClD;AAEA,SAAS,mBAAmB,QAA2B,SAAiB,MAAmC;CACzG,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,QAAW,uBAAO,IAAI,IAAI;CACxC,MAAM,UAAU,OAAO,oBAAoB,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK;CAC7E,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,GAAG,KAAK,GAAG,WAAW,aAAa,QAAQ,6BAA6B;CACrH,OAAO,IAAI,IAAI,QAAQ,OAAO;AAChC;AAEA,SAAS,cAAc,QAA2B,SAAiB,MAAkC;CACnG,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,QAAW,OAAO;CAChC,MAAM,UAAU,OAAO,oBAAoB,OAAO,MAAM,CAAC,CAAC,KAAK;CAC/D,IAAI,OAAO,UAAU,OAAO,GAAG,MAAM,QAAQ,GAAG,KAAK,GAAG,WAAW,aAAa,QAAQ,kBAAkB;CAC1G,OAAO,QAAQ;AACjB;AAEA,SAAS,cAAc,OAAgC,MAAiC;CACtF,IAAI,CAAC,aAAa,KAAK,GAAG,MAAM,QAAQ,MAAM,6DAA6D;CAC3G,OAAO;AACT;AAEA,SAAS,SAAS,MAAsB;CACtC,MAAM,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK;CACvC,MAAM,QAAQ,KACX,QAAQ,sBAAsB,OAAO,CAAC,CACtC,QAAQ,WAAW,GAAG,CAAC,CACvB,KAAK;CACR,OAAO,QAAQ,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC,MAAM;AACvE;AAEA,SAAS,YAAY,OAAwC;CAC3D,OAAO,UAAU,SAAY,cAAe,KAAK,UAAU,KAAK,KAAK;AACvE;AAEA,SAAS,QAAQ,MAAc,SAA0C;CACvE,OAAO,IAAI,wBAAwB;EAAE;EAAS;CAAK,CAAC;AACtD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { l as STUDIO_APP_PATH } from "../HttpPaths-BbS21Jy8.js";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { addRouteMiddleware, addServerHandler, addServerTemplate, addVitePlugin } from "@nuxt/kit";
|
|
4
|
+
import { Effect, FileSystem, Path } from "effect";
|
|
5
|
+
|
|
6
|
+
//#region src/internal/studio-app.ts
|
|
7
|
+
/** A separate HTML entry shares Nuxt's Vite graph, but never its document or Vue app. */
|
|
8
|
+
const registerStudioApp = Effect.fn("CmsNuxtModule.registerStudioApp")(function* (nuxt, resolver) {
|
|
9
|
+
addRouteMiddleware({
|
|
10
|
+
name: "cms-studio-document",
|
|
11
|
+
path: resolver.resolve("./runtime/studio-navigation"),
|
|
12
|
+
global: true
|
|
13
|
+
});
|
|
14
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
15
|
+
const path = yield* Path.Path;
|
|
16
|
+
const packagedHost = resolver.resolve("../studio/host.js");
|
|
17
|
+
const packaged = yield* fileSystem.exists(packagedHost);
|
|
18
|
+
let host = packagedHost;
|
|
19
|
+
if (!packaged) {
|
|
20
|
+
const source = fileURLToPath(import.meta.resolve("@internal/studio/host"));
|
|
21
|
+
const root = path.dirname(path.dirname(source));
|
|
22
|
+
const { build } = yield* Effect.promise(() => import("vite"));
|
|
23
|
+
yield* Effect.promise(() => build({
|
|
24
|
+
root,
|
|
25
|
+
configFile: `${root}/vite.config.ts`
|
|
26
|
+
}));
|
|
27
|
+
host = `${root}/dist/host.js`;
|
|
28
|
+
}
|
|
29
|
+
nuxt.options.alias["#cms/studio"] = host;
|
|
30
|
+
nuxt.options.alias["#cms/studio-styles"] = host.replace(/\.js$/u, ".css?url");
|
|
31
|
+
const entryBase = resolver.resolve("./runtime/studio-entry");
|
|
32
|
+
const entry = `${entryBase}.${(yield* fileSystem.exists(`${entryBase}.ts`)) ? "ts" : "js"}`;
|
|
33
|
+
const assets = `${nuxt.options.app.baseURL}${nuxt.options.app.buildAssetsDir}`.replace(/\/+/gu, "/");
|
|
34
|
+
let entryUrl = `${assets}@fs${entry}`;
|
|
35
|
+
addVitePlugin({
|
|
36
|
+
name: "cms-studio-entry",
|
|
37
|
+
apply: "build",
|
|
38
|
+
buildStart() {
|
|
39
|
+
this.emitFile({
|
|
40
|
+
type: "chunk",
|
|
41
|
+
id: entry,
|
|
42
|
+
name: "cms-studio"
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
generateBundle(_options, bundle) {
|
|
46
|
+
const chunk = Object.values(bundle).find((output) => output.type === "chunk" && output.name === "cms-studio");
|
|
47
|
+
if (chunk) entryUrl = `${nuxt.options.app.baseURL}${chunk.fileName}`;
|
|
48
|
+
}
|
|
49
|
+
}, { server: false });
|
|
50
|
+
const handler = addServerTemplate({
|
|
51
|
+
filename: resolver.resolve("./runtime/studio-shell.virtual.mjs"),
|
|
52
|
+
getContents: () => [`import { createStudioAppHandler } from ${JSON.stringify(resolver.resolve("./runtime/studio-app"))}`, `export default createStudioAppHandler(${JSON.stringify(entryUrl)}, ${JSON.stringify(nuxt.options.dev ? `${assets}@vite/client` : void 0)})`].join("\n")
|
|
53
|
+
});
|
|
54
|
+
addServerHandler({
|
|
55
|
+
handler: handler.filename,
|
|
56
|
+
route: STUDIO_APP_PATH
|
|
57
|
+
});
|
|
58
|
+
addServerHandler({
|
|
59
|
+
handler: handler.filename,
|
|
60
|
+
route: `${STUDIO_APP_PATH}/**:path`
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { registerStudioApp };
|
|
66
|
+
//# sourceMappingURL=studio-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio-app.js","names":[],"sources":["../../../../src/internal/studio-app.ts"],"sourcesContent":["import type { Nuxt } from '@nuxt/schema'\nimport { fileURLToPath } from 'node:url'\nimport { addRouteMiddleware, addServerHandler, addServerTemplate, addVitePlugin, createResolver } from '@nuxt/kit'\nimport { Effect, FileSystem, Path } from 'effect'\nimport { STUDIO_APP_PATH } from '@internal/protocol/HttpPaths'\n\n/** A separate HTML entry shares Nuxt's Vite graph, but never its document or Vue app. */\nexport const registerStudioApp = Effect.fn('CmsNuxtModule.registerStudioApp')(function* (\n nuxt: Nuxt,\n resolver: ReturnType<typeof createResolver>,\n) {\n addRouteMiddleware({\n name: 'cms-studio-document',\n path: resolver.resolve('./runtime/studio-navigation'),\n global: true,\n })\n const fileSystem = yield* FileSystem.FileSystem\n const path = yield* Path.Path\n const packagedHost = resolver.resolve('../studio/host.js')\n const packaged = yield* fileSystem.exists(packagedHost)\n let host = packagedHost\n if (!packaged) {\n const source = fileURLToPath(import.meta.resolve('@internal/studio/host'))\n const root = path.dirname(path.dirname(source))\n const { build } = yield* Effect.promise(() => import('vite'))\n yield* Effect.promise(() => build({ root, configFile: `${root}/vite.config.ts` }))\n host = `${root}/dist/host.js`\n }\n nuxt.options.alias['#cms/studio'] = host\n nuxt.options.alias['#cms/studio-styles'] = host.replace(/\\.js$/u, '.css?url')\n const entryBase = resolver.resolve('./runtime/studio-entry')\n const entry = `${entryBase}.${(yield* fileSystem.exists(`${entryBase}.ts`)) ? 'ts' : 'js'}`\n const assets = `${nuxt.options.app.baseURL}${nuxt.options.app.buildAssetsDir}`.replace(/\\/+/gu, '/')\n let entryUrl = `${assets}@fs${entry}`\n addVitePlugin(\n {\n name: 'cms-studio-entry',\n apply: 'build',\n buildStart() {\n this.emitFile({ type: 'chunk', id: entry, name: 'cms-studio' })\n },\n generateBundle(_options, bundle) {\n const chunk = Object.values(bundle).find((output) => output.type === 'chunk' && output.name === 'cms-studio')\n if (chunk) entryUrl = `${nuxt.options.app.baseURL}${chunk.fileName}`\n },\n },\n { server: false },\n )\n const handler = addServerTemplate({\n filename: resolver.resolve('./runtime/studio-shell.virtual.mjs'),\n getContents: () =>\n [\n `import { createStudioAppHandler } from ${JSON.stringify(resolver.resolve('./runtime/studio-app'))}`,\n `export default createStudioAppHandler(${JSON.stringify(entryUrl)}, ${JSON.stringify(nuxt.options.dev ? `${assets}@vite/client` : undefined)})`,\n ].join('\\n'),\n })\n addServerHandler({ handler: handler.filename, route: STUDIO_APP_PATH })\n addServerHandler({ handler: handler.filename, route: `${STUDIO_APP_PATH}/**:path` })\n})\n"],"mappings":";;;;;;;AAOA,MAAa,oBAAoB,OAAO,GAAG,iCAAiC,CAAC,CAAC,WAC5E,MACA,UACA;CACA,mBAAmB;EACjB,MAAM;EACN,MAAM,SAAS,QAAQ,6BAA6B;EACpD,QAAQ;CACV,CAAC;CACD,MAAM,aAAa,OAAO,WAAW;CACrC,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,eAAe,SAAS,QAAQ,mBAAmB;CACzD,MAAM,WAAW,OAAO,WAAW,OAAO,YAAY;CACtD,IAAI,OAAO;CACX,IAAI,CAAC,UAAU;EACb,MAAM,SAAS,cAAc,YAAY,QAAQ,uBAAuB,CAAC;EACzE,MAAM,OAAO,KAAK,QAAQ,KAAK,QAAQ,MAAM,CAAC;EAC9C,MAAM,EAAE,UAAU,OAAO,OAAO,cAAc,OAAO,OAAO;EAC5D,OAAO,OAAO,cAAc,MAAM;GAAE;GAAM,YAAY,GAAG,KAAK;EAAiB,CAAC,CAAC;EACjF,OAAO,GAAG,KAAK;CACjB;CACA,KAAK,QAAQ,MAAM,iBAAiB;CACpC,KAAK,QAAQ,MAAM,wBAAwB,KAAK,QAAQ,UAAU,UAAU;CAC5E,MAAM,YAAY,SAAS,QAAQ,wBAAwB;CAC3D,MAAM,QAAQ,GAAG,UAAU,IAAI,OAAO,WAAW,OAAO,GAAG,UAAU,IAAI,KAAK,OAAO;CACrF,MAAM,SAAS,GAAG,KAAK,QAAQ,IAAI,UAAU,KAAK,QAAQ,IAAI,iBAAiB,QAAQ,SAAS,GAAG;CACnG,IAAI,WAAW,GAAG,OAAO,KAAK;CAC9B,cACE;EACE,MAAM;EACN,OAAO;EACP,aAAa;GACX,KAAK,SAAS;IAAE,MAAM;IAAS,IAAI;IAAO,MAAM;GAAa,CAAC;EAChE;EACA,eAAe,UAAU,QAAQ;GAC/B,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC,MAAM,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,YAAY;GAC5G,IAAI,OAAO,WAAW,GAAG,KAAK,QAAQ,IAAI,UAAU,MAAM;EAC5D;CACF,GACA,EAAE,QAAQ,MAAM,CAClB;CACA,MAAM,UAAU,kBAAkB;EAChC,UAAU,SAAS,QAAQ,oCAAoC;EAC/D,mBACE,CACE,0CAA0C,KAAK,UAAU,SAAS,QAAQ,sBAAsB,CAAC,KACjG,yCAAyC,KAAK,UAAU,QAAQ,EAAE,IAAI,KAAK,UAAU,KAAK,QAAQ,MAAM,GAAG,OAAO,gBAAgB,MAAS,EAAE,EAC/I,CAAC,CAAC,KAAK,IAAI;CACf,CAAC;CACD,iBAAiB;EAAE,SAAS,QAAQ;EAAU,OAAO;CAAgB,CAAC;CACtE,iBAAiB;EAAE,SAAS,QAAQ;EAAU,OAAO,GAAG,gBAAgB;CAAU,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { a as PreviewSessionId, i as PreviewOrigin } from "./models-C3witQBK.js";
|
|
2
|
+
import { Option, Schema } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region ../protocol/src/internal/preview/location.ts
|
|
5
|
+
const ENABLED_PARAMETER = "_cms_preview";
|
|
6
|
+
const EDITOR_ORIGIN_PARAMETER = "_cms_preview_editor_origin";
|
|
7
|
+
const SESSION_PARAMETER = "_cms_preview_session";
|
|
8
|
+
const PreviewLocationParameters = Schema.Struct({
|
|
9
|
+
editorOrigin: PreviewOrigin,
|
|
10
|
+
sessionId: PreviewSessionId
|
|
11
|
+
});
|
|
12
|
+
function readPreviewLocation(url) {
|
|
13
|
+
if (url.searchParams.get(ENABLED_PARAMETER) !== "1" || url.searchParams.get(EDITOR_ORIGIN_PARAMETER) !== url.origin) return void 0;
|
|
14
|
+
return Schema.decodeUnknownOption(PreviewLocationParameters)({
|
|
15
|
+
editorOrigin: url.searchParams.get(EDITOR_ORIGIN_PARAMETER),
|
|
16
|
+
sessionId: url.searchParams.get(SESSION_PARAMETER)
|
|
17
|
+
}).pipe(Option.getOrUndefined);
|
|
18
|
+
}
|
|
19
|
+
function withPreviewLocation(url, parameters) {
|
|
20
|
+
const next = new URL(url);
|
|
21
|
+
next.searchParams.set(ENABLED_PARAMETER, "1");
|
|
22
|
+
next.searchParams.set(EDITOR_ORIGIN_PARAMETER, parameters.editorOrigin);
|
|
23
|
+
next.searchParams.set(SESSION_PARAMETER, parameters.sessionId);
|
|
24
|
+
return next;
|
|
25
|
+
}
|
|
26
|
+
/** Return a router target only when coordination parameters need to be added or replaced. */
|
|
27
|
+
function previewRedirect(url, parameters) {
|
|
28
|
+
const current = readPreviewLocation(url);
|
|
29
|
+
if (current?.sessionId === parameters.sessionId && current.editorOrigin === parameters.editorOrigin) return void 0;
|
|
30
|
+
const next = withPreviewLocation(url, parameters);
|
|
31
|
+
return `${next.pathname}${next.search}${next.hash}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { readPreviewLocation as n, withPreviewLocation as r, previewRedirect as t };
|
|
36
|
+
//# sourceMappingURL=location-DtYv2aes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location-DtYv2aes.js","names":["PreviewOriginSchema","PreviewSessionIdSchema"],"sources":["../../../../protocol/src/internal/preview/location.ts"],"sourcesContent":["import { Option, Schema } from 'effect'\nimport { PreviewOrigin as PreviewOriginSchema, PreviewSessionId as PreviewSessionIdSchema } from './models'\n\nconst ENABLED_PARAMETER = '_cms_preview'\nconst EDITOR_ORIGIN_PARAMETER = '_cms_preview_editor_origin'\nconst SESSION_PARAMETER = '_cms_preview_session'\n\nconst PreviewLocationParameters = Schema.Struct({\n editorOrigin: PreviewOriginSchema,\n sessionId: PreviewSessionIdSchema,\n})\n\nexport interface PreviewLocationParameters extends Schema.Schema.Type<typeof PreviewLocationParameters> {}\n\nexport function readPreviewLocation(url: URL): PreviewLocationParameters | undefined {\n if (url.searchParams.get(ENABLED_PARAMETER) !== '1' || url.searchParams.get(EDITOR_ORIGIN_PARAMETER) !== url.origin)\n return undefined\n return Schema.decodeUnknownOption(PreviewLocationParameters)({\n editorOrigin: url.searchParams.get(EDITOR_ORIGIN_PARAMETER),\n sessionId: url.searchParams.get(SESSION_PARAMETER),\n }).pipe(Option.getOrUndefined)\n}\n\nexport function withPreviewLocation(url: URL, parameters: PreviewLocationParameters): URL {\n const next = new URL(url)\n next.searchParams.set(ENABLED_PARAMETER, '1')\n next.searchParams.set(EDITOR_ORIGIN_PARAMETER, parameters.editorOrigin)\n next.searchParams.set(SESSION_PARAMETER, parameters.sessionId)\n return next\n}\n\nexport function withoutPreviewLocation(url: URL): URL {\n const next = new URL(url)\n next.searchParams.delete(ENABLED_PARAMETER)\n next.searchParams.delete(EDITOR_ORIGIN_PARAMETER)\n next.searchParams.delete(SESSION_PARAMETER)\n return next\n}\n\n/** Return a router target only when coordination parameters need to be added or replaced. */\nexport function previewRedirect(url: URL, parameters: PreviewLocationParameters): string | undefined {\n const current = readPreviewLocation(url)\n if (current?.sessionId === parameters.sessionId && current.editorOrigin === parameters.editorOrigin) return undefined\n const next = withPreviewLocation(url, parameters)\n return `${next.pathname}${next.search}${next.hash}`\n}\n"],"mappings":";;;;AAGA,MAAM,oBAAoB;AAC1B,MAAM,0BAA0B;AAChC,MAAM,oBAAoB;AAE1B,MAAM,4BAA4B,OAAO,OAAO;CAC9C,cAAcA;CACd,WAAWC;AACb,CAAC;AAID,SAAgB,oBAAoB,KAAiD;CACnF,IAAI,IAAI,aAAa,IAAI,iBAAiB,MAAM,OAAO,IAAI,aAAa,IAAI,uBAAuB,MAAM,IAAI,QAC3G,OAAO;CACT,OAAO,OAAO,oBAAoB,yBAAyB,CAAC,CAAC;EAC3D,cAAc,IAAI,aAAa,IAAI,uBAAuB;EAC1D,WAAW,IAAI,aAAa,IAAI,iBAAiB;CACnD,CAAC,CAAC,CAAC,KAAK,OAAO,cAAc;AAC/B;AAEA,SAAgB,oBAAoB,KAAU,YAA4C;CACxF,MAAM,OAAO,IAAI,IAAI,GAAG;CACxB,KAAK,aAAa,IAAI,mBAAmB,GAAG;CAC5C,KAAK,aAAa,IAAI,yBAAyB,WAAW,YAAY;CACtE,KAAK,aAAa,IAAI,mBAAmB,WAAW,SAAS;CAC7D,OAAO;AACT;;AAWA,SAAgB,gBAAgB,KAAU,YAA2D;CACnG,MAAM,UAAU,oBAAoB,GAAG;CACvC,IAAI,SAAS,cAAc,WAAW,aAAa,QAAQ,iBAAiB,WAAW,cAAc,OAAO;CAC5G,MAAM,OAAO,oBAAoB,KAAK,UAAU;CAChD,OAAO,GAAG,KAAK,WAAW,KAAK,SAAS,KAAK;AAC/C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { vt as EditorNodeId } from "./models-BkMgeaOL.js";
|
|
2
2
|
import { Predicate, Schema } from "effect";
|
|
3
3
|
import { textContent } from "comark/utils";
|
|
4
4
|
|
|
@@ -187,4 +187,4 @@ function jsonObject(value) {
|
|
|
187
187
|
|
|
188
188
|
//#endregion
|
|
189
189
|
export { createEditorNodeId as a, createCmsComarkRenderData as c, toComarkDocument as d, toMutableComarkAttributes as f, withoutEditorMetadata as i, mutableJson as l, editorMetadata as n, editorNodeId as o, identifiedAttributes as r, cmsComarkTextContent as s, assertCanonicalEditorContent as t, mutableJsonObject as u };
|
|
190
|
-
//# sourceMappingURL=metadata-
|
|
190
|
+
//# sourceMappingURL=metadata-DE1Mc2td.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-Czvi3E4K.js","names":["isJsonObject","jsonObject","EditorNodeIdSchema"],"sources":["../../../../document/src/internal/comark/document-adapter.ts","../../../../document/src/internal/editor/identity.ts","../../../../document/src/internal/editor/metadata.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\n/** The only adapter from the validated wire document to Comark's mutable document model. */\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 for (const [name, value] of Object.entries(attributes)) {\n if (name !== '$') result[name] = mutableJson(value)\n }\n const internal = jsonObject(attributes.$)\n const line = internal.line\n const html = binaryFlag(internal.html)\n const block = binaryFlag(internal.block)\n if (Predicate.isNumber(line) || html !== undefined || block !== undefined) {\n const metadata: Record<string, number> = {}\n if (Predicate.isNumber(line)) metadata.line = line\n if (html !== undefined) metadata.html = html\n if (block !== undefined) metadata.block = block\n result.$ = metadata\n }\n return result\n}\n\nexport function mutableJson(value: Schema.Json): Schema.Json {\n if (Array.isArray(value)) return value.map(mutableJson)\n if (isJsonObject(value)) return mutableJsonObject(value)\n return value\n}\n\nfunction toComarkNode(node: MarkdownNode): ComarkNode {\n if (Predicate.isString(node)) return node\n if (node[0] === null) return [null, toMutableComarkAttributes(node[1]), node[2]]\n const [tag, attributes, ...children] = node\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 { EditorNodeId } from '@internal/protocol/Documents'\nimport { EditorNodeId as EditorNodeIdSchema } from '@internal/protocol/Documents'\nimport { Schema } from 'effect'\n\nconst isEditorNodeId = Schema.is(EditorNodeIdSchema)\n\nexport const IDENTIFIED_EDITOR_TYPES = new Set([\n 'blockquote',\n 'bulletList',\n 'cmsBlock',\n 'cmsOpaque',\n 'cmsSlot',\n 'codeBlock',\n 'heading',\n 'horizontalRule',\n 'image',\n 'listItem',\n 'orderedList',\n 'paragraph',\n])\n\nexport function createEditorNodeId(): EditorNodeId {\n const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16))\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n return EditorNodeIdSchema.make(\n `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`,\n )\n}\n\nexport function editorNodeId(value: Schema.Json | undefined): EditorNodeId | undefined {\n return isEditorNodeId(value) ? value : undefined\n}\n\nexport function isIdentifiedEditorType(type: string | undefined): boolean {\n return type !== undefined && IDENTIFIED_EDITOR_TYPES.has(type)\n}\n","import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport type { JSONContent } from '@tiptap/core'\nimport { Predicate, Schema } from 'effect'\nimport { editorNodeId, isIdentifiedEditorType } from './identity'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\ninterface EditorMetadata {\n readonly implicitSlotId?: EditorNodeId\n readonly nodeId: EditorNodeId\n}\n\nexport function assertCanonicalEditorContent(content: JSONContent): void {\n const seen = new Set<EditorNodeId>()\n const visit = (node: JSONContent, path: ReadonlyArray<number>) => {\n if (isIdentifiedEditorNode(node)) {\n const id = editorNodeId(node.attrs?.cmsNodeId)\n if (id === undefined) {\n throw new Error(`Authorable ${node.type} at ${diagnosticPath(path)} has no valid node identity.`)\n }\n if (seen.has(id)) {\n throw new Error(`Authorable ${node.type} at ${diagnosticPath(path)} duplicates node identity \"${id}\".`)\n }\n seen.add(id)\n }\n node.content?.forEach((child, index) => visit(child, [...path, index]))\n }\n visit(content, [])\n}\n\nexport function identifiedAttributes(\n attributes: Schema.JsonObject,\n nodeIdValue: Schema.Json | undefined,\n implicitSlotIdValue?: Schema.Json,\n): Schema.JsonObject {\n const nodeId = editorNodeId(nodeIdValue)\n const implicitSlotId = implicitSlotIdValue === undefined ? undefined : editorNodeId(implicitSlotIdValue)\n if (nodeId === undefined) throw new Error('Cannot project an authorable node without a valid identity.')\n if (implicitSlotIdValue !== undefined && implicitSlotId === undefined)\n throw new Error('Cannot project an implicit slot without a valid identity.')\n\n const internal: Record<string, Schema.Json> = structuredClone(jsonObject(attributes.$))\n if (implicitSlotId === undefined) internal.editor = { nodeId }\n else internal.editor = { implicitSlotId, nodeId }\n const result: Record<string, Schema.Json> = structuredClone(attributes)\n result.$ = internal\n return result\n}\n\nexport function editorMetadata(attributes: Schema.JsonObject): EditorMetadata | undefined {\n const metadata = jsonObject(jsonObject(attributes.$).editor)\n const nodeId = editorNodeId(metadata.nodeId)\n const implicitSlotId = metadata.implicitSlotId === undefined ? undefined : editorNodeId(metadata.implicitSlotId)\n if (nodeId === undefined) return undefined\n if (metadata.implicitSlotId !== undefined && implicitSlotId === undefined) return undefined\n return implicitSlotId === undefined ? { nodeId } : { implicitSlotId, nodeId }\n}\n\nexport function withoutEditorMetadata(body: CmsMarkdownDocument): CmsMarkdownDocument {\n return {\n frontmatter: structuredClone(body.frontmatter),\n meta: structuredClone(body.meta),\n nodes: body.nodes.map(cleanNode),\n }\n}\n\nfunction cleanNode(node: MarkdownNode): MarkdownNode {\n if (Predicate.isString(node)) return node\n if (node[0] === null) {\n const cleanAttributes = cleanNodeAttributes(node[1])\n return [null, cleanAttributes, node[2]]\n }\n const [tag, attributes, ...children] = node\n return [tag, cleanNodeAttributes(attributes), ...children.map(cleanNode)]\n}\n\nfunction cleanNodeAttributes(attributes: Schema.JsonObject): Record<string, Schema.Json> {\n const cleanAttributes: Record<string, Schema.Json> = structuredClone(attributes)\n const internal = jsonObject(cleanAttributes.$)\n if (internal.editor !== undefined) {\n const { editor: _editor, ...remaining } = internal\n if (Object.keys(remaining).length) cleanAttributes.$ = remaining\n else delete cleanAttributes.$\n }\n return cleanAttributes\n}\n\nfunction isIdentifiedEditorNode(node: JSONContent): boolean {\n if (!isIdentifiedEditorType(node.type)) return false\n if (node.attrs?.cmsSynthetic === true || node.attrs?.cmsTransient === true) return false\n return node.type !== 'paragraph' || Boolean(node.content?.length)\n}\n\nfunction diagnosticPath(path: ReadonlyArray<number>): string {\n return path.length ? path.join('.') : 'document root'\n}\n\nfunction jsonObject(value: Schema.Json | undefined): Schema.JsonObject {\n return isJsonObject(value) ? value : {}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"metadata-DE1Mc2td.js","names":["isJsonObject","jsonObject","EditorNodeIdSchema"],"sources":["../../../../document/src/internal/comark/document-adapter.ts","../../../../document/src/internal/editor/identity.ts","../../../../document/src/internal/editor/metadata.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\n/** The only adapter from the validated wire document to Comark's mutable document model. */\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 for (const [name, value] of Object.entries(attributes)) {\n if (name !== '$') result[name] = mutableJson(value)\n }\n const internal = jsonObject(attributes.$)\n const line = internal.line\n const html = binaryFlag(internal.html)\n const block = binaryFlag(internal.block)\n if (Predicate.isNumber(line) || html !== undefined || block !== undefined) {\n const metadata: Record<string, number> = {}\n if (Predicate.isNumber(line)) metadata.line = line\n if (html !== undefined) metadata.html = html\n if (block !== undefined) metadata.block = block\n result.$ = metadata\n }\n return result\n}\n\nexport function mutableJson(value: Schema.Json): Schema.Json {\n if (Array.isArray(value)) return value.map(mutableJson)\n if (isJsonObject(value)) return mutableJsonObject(value)\n return value\n}\n\nfunction toComarkNode(node: MarkdownNode): ComarkNode {\n if (Predicate.isString(node)) return node\n if (node[0] === null) return [null, toMutableComarkAttributes(node[1]), node[2]]\n const [tag, attributes, ...children] = node\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 { EditorNodeId } from '@internal/protocol/Documents'\nimport { EditorNodeId as EditorNodeIdSchema } from '@internal/protocol/Documents'\nimport { Schema } from 'effect'\n\nconst isEditorNodeId = Schema.is(EditorNodeIdSchema)\n\nexport const IDENTIFIED_EDITOR_TYPES = new Set([\n 'blockquote',\n 'bulletList',\n 'cmsBlock',\n 'cmsOpaque',\n 'cmsSlot',\n 'codeBlock',\n 'heading',\n 'horizontalRule',\n 'image',\n 'listItem',\n 'orderedList',\n 'paragraph',\n])\n\nexport function createEditorNodeId(): EditorNodeId {\n const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16))\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n return EditorNodeIdSchema.make(\n `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`,\n )\n}\n\nexport function editorNodeId(value: Schema.Json | undefined): EditorNodeId | undefined {\n return isEditorNodeId(value) ? value : undefined\n}\n\nexport function isIdentifiedEditorType(type: string | undefined): boolean {\n return type !== undefined && IDENTIFIED_EDITOR_TYPES.has(type)\n}\n","import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport type { JSONContent } from '@tiptap/core'\nimport { Predicate, Schema } from 'effect'\nimport { editorNodeId, isIdentifiedEditorType } from './identity'\n\nconst isJsonObject = Schema.is(Schema.JsonObject)\n\ninterface EditorMetadata {\n readonly implicitSlotId?: EditorNodeId\n readonly nodeId: EditorNodeId\n}\n\nexport function assertCanonicalEditorContent(content: JSONContent): void {\n const seen = new Set<EditorNodeId>()\n const visit = (node: JSONContent, path: ReadonlyArray<number>) => {\n if (isIdentifiedEditorNode(node)) {\n const id = editorNodeId(node.attrs?.cmsNodeId)\n if (id === undefined) {\n throw new Error(`Authorable ${node.type} at ${diagnosticPath(path)} has no valid node identity.`)\n }\n if (seen.has(id)) {\n throw new Error(`Authorable ${node.type} at ${diagnosticPath(path)} duplicates node identity \"${id}\".`)\n }\n seen.add(id)\n }\n node.content?.forEach((child, index) => visit(child, [...path, index]))\n }\n visit(content, [])\n}\n\nexport function identifiedAttributes(\n attributes: Schema.JsonObject,\n nodeIdValue: Schema.Json | undefined,\n implicitSlotIdValue?: Schema.Json,\n): Schema.JsonObject {\n const nodeId = editorNodeId(nodeIdValue)\n const implicitSlotId = implicitSlotIdValue === undefined ? undefined : editorNodeId(implicitSlotIdValue)\n if (nodeId === undefined) throw new Error('Cannot project an authorable node without a valid identity.')\n if (implicitSlotIdValue !== undefined && implicitSlotId === undefined)\n throw new Error('Cannot project an implicit slot without a valid identity.')\n\n const internal: Record<string, Schema.Json> = structuredClone(jsonObject(attributes.$))\n if (implicitSlotId === undefined) internal.editor = { nodeId }\n else internal.editor = { implicitSlotId, nodeId }\n const result: Record<string, Schema.Json> = structuredClone(attributes)\n result.$ = internal\n return result\n}\n\nexport function editorMetadata(attributes: Schema.JsonObject): EditorMetadata | undefined {\n const metadata = jsonObject(jsonObject(attributes.$).editor)\n const nodeId = editorNodeId(metadata.nodeId)\n const implicitSlotId = metadata.implicitSlotId === undefined ? undefined : editorNodeId(metadata.implicitSlotId)\n if (nodeId === undefined) return undefined\n if (metadata.implicitSlotId !== undefined && implicitSlotId === undefined) return undefined\n return implicitSlotId === undefined ? { nodeId } : { implicitSlotId, nodeId }\n}\n\nexport function withoutEditorMetadata(body: CmsMarkdownDocument): CmsMarkdownDocument {\n return {\n frontmatter: structuredClone(body.frontmatter),\n meta: structuredClone(body.meta),\n nodes: body.nodes.map(cleanNode),\n }\n}\n\nfunction cleanNode(node: MarkdownNode): MarkdownNode {\n if (Predicate.isString(node)) return node\n if (node[0] === null) {\n const cleanAttributes = cleanNodeAttributes(node[1])\n return [null, cleanAttributes, node[2]]\n }\n const [tag, attributes, ...children] = node\n return [tag, cleanNodeAttributes(attributes), ...children.map(cleanNode)]\n}\n\nfunction cleanNodeAttributes(attributes: Schema.JsonObject): Record<string, Schema.Json> {\n const cleanAttributes: Record<string, Schema.Json> = structuredClone(attributes)\n const internal = jsonObject(cleanAttributes.$)\n if (internal.editor !== undefined) {\n const { editor: _editor, ...remaining } = internal\n if (Object.keys(remaining).length) cleanAttributes.$ = remaining\n else delete cleanAttributes.$\n }\n return cleanAttributes\n}\n\nfunction isIdentifiedEditorNode(node: JSONContent): boolean {\n if (!isIdentifiedEditorType(node.type)) return false\n if (node.attrs?.cmsSynthetic === true || node.attrs?.cmsTransient === true) return false\n return node.type !== 'paragraph' || Boolean(node.content?.length)\n}\n\nfunction diagnosticPath(path: ReadonlyArray<number>): string {\n return path.length ? path.join('.') : 'document root'\n}\n\nfunction jsonObject(value: Schema.Json | undefined): Schema.JsonObject {\n return isJsonObject(value) ? value : {}\n}\n"],"mappings":";;;;;AAUA,MAAMA,iBAAe,OAAO,GAAG,OAAO,UAAU;;AAGhD,SAAgB,iBAAiB,UAAuD;CACtF,OAAO;EACL,aAAa,kBAAkB,SAAS,WAAW;EACnD,MAAM,kBAAkB,SAAS,IAAI;EACrC,OAAO,SAAS,MAAM,IAAI,YAAY;CACxC;AACF;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,OAAO;EACL,MAAM,CAAC;EACP,aAAa,kBAAkB,SAAS,WAAW;EACnD,MAAM,kBAAkB,SAAS,IAAI;EACrC,OAAO,CAAC;CACV;AACF;;AAGA,SAAgB,qBAAqB,MAA4B;CAC/D,OAAO,YAAY,aAAa,IAAI,GAAG,EAAE,uBAAuB,KAAK,CAAC;AACxE;AAEA,SAAgB,0BAA0B,YAAsD;CAC9F,MAAM,SAAgC,CAAC;CACvC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,UAAU,GACnD,IAAI,SAAS,KAAK,OAAO,QAAQ,YAAY,KAAK;CAEpD,MAAM,WAAWC,aAAW,WAAW,CAAC;CACxC,MAAM,OAAO,SAAS;CACtB,MAAM,OAAO,WAAW,SAAS,IAAI;CACrC,MAAM,QAAQ,WAAW,SAAS,KAAK;CACvC,IAAI,UAAU,SAAS,IAAI,KAAK,SAAS,UAAa,UAAU,QAAW;EACzE,MAAM,WAAmC,CAAC;EAC1C,IAAI,UAAU,SAAS,IAAI,GAAG,SAAS,OAAO;EAC9C,IAAI,SAAS,QAAW,SAAS,OAAO;EACxC,IAAI,UAAU,QAAW,SAAS,QAAQ;EAC1C,OAAO,IAAI;CACb;CACA,OAAO;AACT;AAEA,SAAgB,YAAY,OAAiC;CAC3D,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,WAAW;CACtD,IAAID,eAAa,KAAK,GAAG,OAAO,kBAAkB,KAAK;CACvD,OAAO;AACT;AAEA,SAAS,aAAa,MAAgC;CACpD,IAAI,UAAU,SAAS,IAAI,GAAG,OAAO;CACrC,IAAI,KAAK,OAAO,MAAM,OAAO;EAAC;EAAM,0BAA0B,KAAK,EAAE;EAAG,KAAK;CAAE;CAC/E,MAAM,CAAC,KAAK,YAAY,GAAG,YAAY;CACvC,OAAO;EAAC;EAAK,0BAA0B,UAAU;EAAG,GAAG,SAAS,IAAI,YAAY;CAAC;AACnF;AAEA,SAAgB,kBAAkB,OAAuD;CACvF,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC;AAClG;AAEA,SAAS,WAAW,OAAmD;CACrE,OAAO,UAAU,KAAK,UAAU,IAAI,QAAQ;AAC9C;AAEA,SAASC,aAAW,OAAmD;CACrE,OAAOD,eAAa,KAAK,IAAI,QAAQ,CAAC;AACxC;;;;ACzEA,MAAM,iBAAiB,OAAO,GAAGE,YAAkB;AAEnD,MAAa,0CAA0B,IAAI,IAAI;CAC7C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAgB,qBAAmC;CACjD,MAAM,QAAQ,WAAW,OAAO,gCAAgB,IAAI,WAAW,EAAE,CAAC;CAClE,MAAM,MAAO,MAAM,MAAM,KAAK,KAAQ;CACtC,MAAM,MAAO,MAAM,MAAM,KAAK,KAAQ;CACtC,MAAM,MAAM,MAAM,KAAK,QAAQ,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;CACnF,OAAOA,aAAmB,KACxB,GAAG,IAAI,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,MAAM,GAAG,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,EAAE,GAClG;AACF;AAEA,SAAgB,aAAa,OAA0D;CACrF,OAAO,eAAe,KAAK,IAAI,QAAQ;AACzC;AAEA,SAAgB,uBAAuB,MAAmC;CACxE,OAAO,SAAS,UAAa,wBAAwB,IAAI,IAAI;AAC/D;;;;AC/BA,MAAM,eAAe,OAAO,GAAG,OAAO,UAAU;AAOhD,SAAgB,6BAA6B,SAA4B;CACvE,MAAM,uBAAO,IAAI,IAAkB;CACnC,MAAM,SAAS,MAAmB,SAAgC;EAChE,IAAI,uBAAuB,IAAI,GAAG;GAChC,MAAM,KAAK,aAAa,KAAK,OAAO,SAAS;GAC7C,IAAI,OAAO,QACT,MAAM,IAAI,MAAM,cAAc,KAAK,KAAK,MAAM,eAAe,IAAI,EAAE,6BAA6B;GAElG,IAAI,KAAK,IAAI,EAAE,GACb,MAAM,IAAI,MAAM,cAAc,KAAK,KAAK,MAAM,eAAe,IAAI,EAAE,6BAA6B,GAAG,GAAG;GAExG,KAAK,IAAI,EAAE;EACb;EACA,KAAK,SAAS,SAAS,OAAO,UAAU,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC;CACxE;CACA,MAAM,SAAS,CAAC,CAAC;AACnB;AAEA,SAAgB,qBACd,YACA,aACA,qBACmB;CACnB,MAAM,SAAS,aAAa,WAAW;CACvC,MAAM,iBAAiB,wBAAwB,SAAY,SAAY,aAAa,mBAAmB;CACvG,IAAI,WAAW,QAAW,MAAM,IAAI,MAAM,6DAA6D;CACvG,IAAI,wBAAwB,UAAa,mBAAmB,QAC1D,MAAM,IAAI,MAAM,2DAA2D;CAE7E,MAAM,WAAwC,gBAAgB,WAAW,WAAW,CAAC,CAAC;CACtF,IAAI,mBAAmB,QAAW,SAAS,SAAS,EAAE,OAAO;MACxD,SAAS,SAAS;EAAE;EAAgB;CAAO;CAChD,MAAM,SAAsC,gBAAgB,UAAU;CACtE,OAAO,IAAI;CACX,OAAO;AACT;AAEA,SAAgB,eAAe,YAA2D;CACxF,MAAM,WAAW,WAAW,WAAW,WAAW,CAAC,CAAC,CAAC,MAAM;CAC3D,MAAM,SAAS,aAAa,SAAS,MAAM;CAC3C,MAAM,iBAAiB,SAAS,mBAAmB,SAAY,SAAY,aAAa,SAAS,cAAc;CAC/G,IAAI,WAAW,QAAW,OAAO;CACjC,IAAI,SAAS,mBAAmB,UAAa,mBAAmB,QAAW,OAAO;CAClF,OAAO,mBAAmB,SAAY,EAAE,OAAO,IAAI;EAAE;EAAgB;CAAO;AAC9E;AAEA,SAAgB,sBAAsB,MAAgD;CACpF,OAAO;EACL,aAAa,gBAAgB,KAAK,WAAW;EAC7C,MAAM,gBAAgB,KAAK,IAAI;EAC/B,OAAO,KAAK,MAAM,IAAI,SAAS;CACjC;AACF;AAEA,SAAS,UAAU,MAAkC;CACnD,IAAI,UAAU,SAAS,IAAI,GAAG,OAAO;CACrC,IAAI,KAAK,OAAO,MAEd,OAAO;EAAC;EADgB,oBAAoB,KAAK,EACrB;EAAG,KAAK;CAAE;CAExC,MAAM,CAAC,KAAK,YAAY,GAAG,YAAY;CACvC,OAAO;EAAC;EAAK,oBAAoB,UAAU;EAAG,GAAG,SAAS,IAAI,SAAS;CAAC;AAC1E;AAEA,SAAS,oBAAoB,YAA4D;CACvF,MAAM,kBAA+C,gBAAgB,UAAU;CAC/E,MAAM,WAAW,WAAW,gBAAgB,CAAC;CAC7C,IAAI,SAAS,WAAW,QAAW;EACjC,MAAM,EAAE,QAAQ,SAAS,GAAG,cAAc;EAC1C,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,QAAQ,gBAAgB,IAAI;OAClD,OAAO,gBAAgB;CAC9B;CACA,OAAO;AACT;AAEA,SAAS,uBAAuB,MAA4B;CAC1D,IAAI,CAAC,uBAAuB,KAAK,IAAI,GAAG,OAAO;CAC/C,IAAI,KAAK,OAAO,iBAAiB,QAAQ,KAAK,OAAO,iBAAiB,MAAM,OAAO;CACnF,OAAO,KAAK,SAAS,eAAe,QAAQ,KAAK,SAAS,MAAM;AAClE;AAEA,SAAS,eAAe,MAAqC;CAC3D,OAAO,KAAK,SAAS,KAAK,KAAK,GAAG,IAAI;AACxC;AAEA,SAAS,WAAW,OAAmD;CACrE,OAAO,aAAa,KAAK,IAAI,QAAQ,CAAC;AACxC"}
|
|
@@ -21,6 +21,11 @@ const RevisionNumber = nonNegativeInt.pipe(Schema.brand("RevisionNumber"));
|
|
|
21
21
|
const Slug = Schema.String.check(Schema.isPattern(slugPattern)).pipe(Schema.brand("Slug"));
|
|
22
22
|
const SourcePath = Schema.String.check(Schema.isPattern(sourcePathPattern)).pipe(Schema.brand("SourcePath"));
|
|
23
23
|
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region ../protocol/src/Identity.ts
|
|
26
|
+
/** Cross-domain request correlation; decode unknown strings before crossing a seam. */
|
|
27
|
+
const RequestId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("RequestId"));
|
|
28
|
+
|
|
24
29
|
//#endregion
|
|
25
30
|
//#region ../protocol/src/internal/configuration/scalars.ts
|
|
26
31
|
const collectionNamePattern = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/u;
|
|
@@ -31,6 +36,224 @@ const CollectionName = Schema.String.check(Schema.isPattern(collectionNamePatter
|
|
|
31
36
|
const Locale = Schema.String.check(Schema.isPattern(localePattern)).pipe(Schema.brand("Locale"));
|
|
32
37
|
const SourceDirectory = Schema.String.check(Schema.isPattern(sourceDirectoryPattern)).pipe(Schema.brand("SourceDirectory"));
|
|
33
38
|
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region ../protocol/src/Media.ts
|
|
41
|
+
/**
|
|
42
|
+
* Media wire models. Search pages are newest-first with opaque continuation cursors; only ready
|
|
43
|
+
* assets are public results, and names, folders, and object keys are validated path-safe values.
|
|
44
|
+
*/
|
|
45
|
+
const hasUnsafeMediaCharacter = (value) => {
|
|
46
|
+
for (const character of value) {
|
|
47
|
+
const codePoint = character.codePointAt(0);
|
|
48
|
+
if (character === "\\" || codePoint !== void 0 && (codePoint <= 31 || codePoint === 127)) return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
};
|
|
52
|
+
const isSafeMediaPath = (value, allowEmpty) => {
|
|
53
|
+
if (value.length === 0) return allowEmpty;
|
|
54
|
+
if (value !== value.trim() || value.startsWith("/") || value.endsWith("/") || hasUnsafeMediaCharacter(value)) return false;
|
|
55
|
+
return value.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
56
|
+
};
|
|
57
|
+
const safeMediaFolder = Schema.makeFilter((value) => isSafeMediaPath(value, true), { expected: "a provider-relative media folder without traversal segments" });
|
|
58
|
+
const safeMediaObjectKey = Schema.makeFilter((value) => isSafeMediaPath(value, false), { expected: "a non-empty provider-relative media object key without traversal segments" });
|
|
59
|
+
const safeMediaName = Schema.makeFilter((value) => value.length > 0 && value.length <= 255 && value === value.trim() && value !== "." && value !== ".." && !value.includes("/") && !hasUnsafeMediaCharacter(value), { expected: "a safe media file name of at most 255 characters" });
|
|
60
|
+
const MediaId = Schema.String.check(Schema.isUUID()).pipe(Schema.brand("MediaId"));
|
|
61
|
+
const MediaFolder = Schema.String.check(Schema.isMaxLength(512), safeMediaFolder).pipe(Schema.brand("MediaFolder"));
|
|
62
|
+
const MediaObjectKey = Schema.String.check(Schema.isMaxLength(1024), safeMediaObjectKey).pipe(Schema.brand("MediaObjectKey"));
|
|
63
|
+
const MediaName = Schema.String.check(safeMediaName).pipe(Schema.brand("MediaName"));
|
|
64
|
+
const MediaCursor = Schema.NonEmptyString.pipe(Schema.brand("MediaCursor"));
|
|
65
|
+
const ImageMimeType = Schema.Literals([
|
|
66
|
+
"image/avif",
|
|
67
|
+
"image/gif",
|
|
68
|
+
"image/jpeg",
|
|
69
|
+
"image/png",
|
|
70
|
+
"image/webp"
|
|
71
|
+
]);
|
|
72
|
+
const MediaStatus = Schema.Literals([
|
|
73
|
+
"uploading",
|
|
74
|
+
"ready",
|
|
75
|
+
"deleting"
|
|
76
|
+
]);
|
|
77
|
+
const MediaByteSize = Schema.Int.check(Schema.isGreaterThan(0));
|
|
78
|
+
const MediaAsset = Schema.Struct({
|
|
79
|
+
kind: Schema.tag("image"),
|
|
80
|
+
id: MediaId,
|
|
81
|
+
objectKey: MediaObjectKey,
|
|
82
|
+
url: Schema.NonEmptyString,
|
|
83
|
+
name: MediaName,
|
|
84
|
+
folder: MediaFolder,
|
|
85
|
+
mimeType: ImageMimeType,
|
|
86
|
+
byteSize: MediaByteSize,
|
|
87
|
+
createdAt: Schema.DateTimeUtcFromString,
|
|
88
|
+
updatedAt: Schema.DateTimeUtcFromString,
|
|
89
|
+
status: MediaStatus
|
|
90
|
+
}).annotate({ identifier: "MediaAsset" });
|
|
91
|
+
const MediaUpload = Schema.Struct({
|
|
92
|
+
name: MediaName,
|
|
93
|
+
folder: Schema.optionalKey(MediaFolder),
|
|
94
|
+
declaredMimeType: Schema.optionalKey(Schema.NonEmptyString),
|
|
95
|
+
declaredByteSize: MediaByteSize
|
|
96
|
+
}).annotate({ identifier: "MediaUpload" });
|
|
97
|
+
const MediaQuery = Schema.Struct({
|
|
98
|
+
cursor: Schema.optionalKey(MediaCursor),
|
|
99
|
+
folder: Schema.optionalKey(MediaFolder),
|
|
100
|
+
search: Schema.optionalKey(Schema.NonEmptyString.check(Schema.isMaxLength(200))),
|
|
101
|
+
limit: Schema.optionalKey(Schema.Int.check(Schema.isBetween({
|
|
102
|
+
minimum: 1,
|
|
103
|
+
maximum: 100
|
|
104
|
+
})))
|
|
105
|
+
}).annotate({ identifier: "MediaQuery" });
|
|
106
|
+
const ReadyMediaAssets = Schema.Array(MediaAsset).check(Schema.makeFilter((assets) => assets.every((asset) => asset.status === "ready"), { expected: "media assets whose lifecycle status is ready" }));
|
|
107
|
+
const MediaPage = Schema.Struct({
|
|
108
|
+
assets: ReadyMediaAssets,
|
|
109
|
+
folders: Schema.Array(MediaFolder),
|
|
110
|
+
nextCursor: Schema.optionalKey(MediaCursor),
|
|
111
|
+
total: nonNegativeInt
|
|
112
|
+
}).annotate({ identifier: "MediaPage" });
|
|
113
|
+
const MediaReference = Schema.Struct({
|
|
114
|
+
documentId: DocumentId,
|
|
115
|
+
path: PublicPath,
|
|
116
|
+
sourcePath: SourcePath,
|
|
117
|
+
objectKey: MediaObjectKey,
|
|
118
|
+
nodePath: Schema.Array(nonNegativeInt)
|
|
119
|
+
}).annotate({ identifier: "MediaReference" });
|
|
120
|
+
const MediaObjectMismatch = Schema.Struct({
|
|
121
|
+
asset: MediaAsset,
|
|
122
|
+
storedByteSize: MediaByteSize,
|
|
123
|
+
storedMimeType: Schema.optionalKey(ImageMimeType)
|
|
124
|
+
}).annotate({ identifier: "MediaObjectMismatch" });
|
|
125
|
+
const MediaIntegrityReport = Schema.Struct({
|
|
126
|
+
missingAssets: Schema.Array(MediaReference),
|
|
127
|
+
missingObjects: Schema.Array(MediaAsset),
|
|
128
|
+
mismatchedObjects: Schema.Array(MediaObjectMismatch),
|
|
129
|
+
orphanedObjectKeys: Schema.Array(MediaObjectKey),
|
|
130
|
+
unusedAssets: Schema.Array(MediaAsset)
|
|
131
|
+
}).annotate({ identifier: "MediaIntegrityReport" });
|
|
132
|
+
const MediaCleanupReport = Schema.Struct({ removedObjectKeys: Schema.Array(MediaObjectKey) }).annotate({ identifier: "MediaCleanupReport" });
|
|
133
|
+
var MediaNotFound = class extends Schema.TaggedError()("Media.NotFound", { mediaId: MediaId }) {};
|
|
134
|
+
var MediaReferenced = class extends Schema.TaggedError()("Media.Referenced", {
|
|
135
|
+
mediaId: MediaId,
|
|
136
|
+
references: Schema.Array(MediaReference)
|
|
137
|
+
}) {};
|
|
138
|
+
var MediaConflict = class extends Schema.TaggedError()("Media.Conflict", { mediaId: MediaId }) {};
|
|
139
|
+
var MediaInvalid = class extends Schema.TaggedError()("Media.Invalid", { message: Schema.NonEmptyString }) {};
|
|
140
|
+
var MediaTooLarge = class extends Schema.TaggedError()("Media.TooLarge", {
|
|
141
|
+
declaredByteSize: MediaByteSize,
|
|
142
|
+
maxUploadBytes: MediaByteSize
|
|
143
|
+
}) {};
|
|
144
|
+
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region ../protocol/src/AccessControl.ts
|
|
147
|
+
/** Wire-visible Studio actors, request identity, roles, access decisions, and denials. */
|
|
148
|
+
const ROLES = [
|
|
149
|
+
"administrator",
|
|
150
|
+
"editor",
|
|
151
|
+
"viewer"
|
|
152
|
+
];
|
|
153
|
+
const Role = Schema.Literals(ROLES);
|
|
154
|
+
const StudioActor = Schema.Struct({
|
|
155
|
+
id: Schema.NonEmptyString,
|
|
156
|
+
email: Schema.NonEmptyString,
|
|
157
|
+
name: Schema.NonEmptyString,
|
|
158
|
+
roles: Schema.Array(Schema.NonEmptyString)
|
|
159
|
+
}).annotate({ identifier: "StudioActor" });
|
|
160
|
+
const StudioRequestContext = Schema.Struct({
|
|
161
|
+
actor: StudioActor,
|
|
162
|
+
requestId: RequestId
|
|
163
|
+
}).annotate({ identifier: "StudioRequestContext" });
|
|
164
|
+
const DOCUMENT_ACTIONS = [
|
|
165
|
+
"document.browse",
|
|
166
|
+
"document.read",
|
|
167
|
+
"document.trash",
|
|
168
|
+
"document.validate",
|
|
169
|
+
"document.create",
|
|
170
|
+
"document.update",
|
|
171
|
+
"document.move",
|
|
172
|
+
"document.remove",
|
|
173
|
+
"document.restore",
|
|
174
|
+
"document.undelete",
|
|
175
|
+
"document.publish",
|
|
176
|
+
"document.unpublish",
|
|
177
|
+
"document.duplicate",
|
|
178
|
+
"document.history"
|
|
179
|
+
];
|
|
180
|
+
const DocumentAction = Schema.Literals(DOCUMENT_ACTIONS);
|
|
181
|
+
const DocumentCatalogResource = Schema.Struct({ kind: Schema.tag("catalog") });
|
|
182
|
+
const CollectionResource = Schema.Struct({
|
|
183
|
+
kind: Schema.tag("collection"),
|
|
184
|
+
collection: CollectionName,
|
|
185
|
+
locale: Schema.optionalKey(Locale)
|
|
186
|
+
});
|
|
187
|
+
const DocumentResource = Schema.Struct({
|
|
188
|
+
kind: Schema.tag("document"),
|
|
189
|
+
documentId: DocumentId
|
|
190
|
+
});
|
|
191
|
+
const DocumentAccessResource = Schema.Union([
|
|
192
|
+
DocumentCatalogResource,
|
|
193
|
+
CollectionResource,
|
|
194
|
+
DocumentResource
|
|
195
|
+
]).pipe(Schema.toTaggedUnion("kind"));
|
|
196
|
+
const DocumentAccessDecision = Schema.Struct({
|
|
197
|
+
action: DocumentAction,
|
|
198
|
+
resource: DocumentAccessResource
|
|
199
|
+
}).annotate({ identifier: "DocumentAccessDecision" });
|
|
200
|
+
const MEDIA_ACTIONS = [
|
|
201
|
+
"media.read",
|
|
202
|
+
"media.search",
|
|
203
|
+
"media.integrity",
|
|
204
|
+
"media.upload",
|
|
205
|
+
"media.replace",
|
|
206
|
+
"media.remove",
|
|
207
|
+
"media.cleanup"
|
|
208
|
+
];
|
|
209
|
+
const MediaAction = Schema.Literals(MEDIA_ACTIONS);
|
|
210
|
+
const MediaCatalogResource = Schema.Struct({ kind: Schema.tag("media-catalog") });
|
|
211
|
+
const MediaAssetResource = Schema.Struct({
|
|
212
|
+
kind: Schema.tag("media-asset"),
|
|
213
|
+
mediaId: MediaId
|
|
214
|
+
});
|
|
215
|
+
const MediaFolderResource = Schema.Struct({
|
|
216
|
+
kind: Schema.tag("media-folder"),
|
|
217
|
+
folder: MediaFolder
|
|
218
|
+
});
|
|
219
|
+
const MediaResource = Schema.Union([
|
|
220
|
+
MediaCatalogResource,
|
|
221
|
+
MediaAssetResource,
|
|
222
|
+
MediaFolderResource
|
|
223
|
+
]).pipe(Schema.toTaggedUnion("kind"));
|
|
224
|
+
const MediaAccessDecision = Schema.Struct({
|
|
225
|
+
action: MediaAction,
|
|
226
|
+
resource: MediaResource
|
|
227
|
+
}).annotate({ identifier: "MediaAccessDecision" });
|
|
228
|
+
const ActivityResource = Schema.Struct({ kind: Schema.tag("activity") });
|
|
229
|
+
const ActivityAccessDecision = Schema.Struct({
|
|
230
|
+
action: Schema.Literal("activity.read"),
|
|
231
|
+
resource: ActivityResource
|
|
232
|
+
}).annotate({ identifier: "ActivityAccessDecision" });
|
|
233
|
+
const STUDIO_ACTIONS = [
|
|
234
|
+
...DOCUMENT_ACTIONS,
|
|
235
|
+
...MEDIA_ACTIONS,
|
|
236
|
+
"activity.read"
|
|
237
|
+
];
|
|
238
|
+
const StudioAction = Schema.Literals(STUDIO_ACTIONS);
|
|
239
|
+
const StudioResource = Schema.Union([
|
|
240
|
+
DocumentAccessResource,
|
|
241
|
+
MediaResource,
|
|
242
|
+
ActivityResource
|
|
243
|
+
]);
|
|
244
|
+
const StudioAccessDecision = Schema.Union([
|
|
245
|
+
DocumentAccessDecision,
|
|
246
|
+
MediaAccessDecision,
|
|
247
|
+
ActivityAccessDecision
|
|
248
|
+
]);
|
|
249
|
+
var AuthenticationRequired = class extends Schema.TaggedError()("Studio.AuthenticationRequired", {}) {};
|
|
250
|
+
var StudioEntryDenied = class extends Schema.TaggedError()("Studio.EntryDenied", {}) {};
|
|
251
|
+
var AccessDenied = class extends Schema.TaggedError()("Studio.AccessDenied", {
|
|
252
|
+
action: StudioAction,
|
|
253
|
+
actorId: StudioActor.fields.id,
|
|
254
|
+
resource: StudioResource
|
|
255
|
+
}) {};
|
|
256
|
+
|
|
34
257
|
//#endregion
|
|
35
258
|
//#region ../protocol/src/internal/documents/models.ts
|
|
36
259
|
const DocumentIssueCode = Schema.Literals([
|
|
@@ -119,7 +342,13 @@ const CompiledDocument = Schema.Struct({
|
|
|
119
342
|
engineFingerprint: Schema.NonEmptyString,
|
|
120
343
|
source: CompiledDocumentSource
|
|
121
344
|
}).annotate({ identifier: "CompiledDocument" });
|
|
345
|
+
const documentAttribution = {
|
|
346
|
+
createdBy: Schema.optionalKey(StudioActor),
|
|
347
|
+
editedBy: Schema.optionalKey(StudioActor),
|
|
348
|
+
editedAt: Schema.optionalKey(Schema.DateTimeUtcFromString)
|
|
349
|
+
};
|
|
122
350
|
const DocumentSource = Schema.Struct({
|
|
351
|
+
...documentAttribution,
|
|
123
352
|
documentId: DocumentId,
|
|
124
353
|
sourcePath: SourcePath,
|
|
125
354
|
markdown: Schema.String,
|
|
@@ -146,11 +375,17 @@ const DocumentImportReport = Schema.Struct({
|
|
|
146
375
|
updated: nonNegativeInt
|
|
147
376
|
}).annotate({ identifier: "DocumentImportReport" });
|
|
148
377
|
const DocumentSummary = Schema.Struct({
|
|
378
|
+
...documentAttribution,
|
|
379
|
+
publishedVersion: Schema.optionalKey(DocumentVersion),
|
|
380
|
+
publishedPath: Schema.optionalKey(PublicPath),
|
|
149
381
|
sourcePath: SourcePath,
|
|
150
382
|
version: DocumentVersion,
|
|
151
383
|
document: CompiledDocument
|
|
152
384
|
}).annotate({ identifier: "DocumentSummary" });
|
|
153
385
|
const DeletedDocument = Schema.Struct({
|
|
386
|
+
title: Schema.optionalKey(Schema.String),
|
|
387
|
+
path: Schema.optionalKey(PublicPath),
|
|
388
|
+
trashBatchId: Schema.optionalKey(DocumentVersion),
|
|
154
389
|
documentId: DocumentId,
|
|
155
390
|
deletedAt: Schema.DateTimeUtcFromString,
|
|
156
391
|
sourcePath: SourcePath,
|
|
@@ -255,6 +490,15 @@ const MoveDocumentInput = Schema.Struct({
|
|
|
255
490
|
location: DocumentLocation,
|
|
256
491
|
...documentMutationMetadata
|
|
257
492
|
}).annotate({ identifier: "MoveDocumentInput" });
|
|
493
|
+
const DuplicateDocumentInput = Schema.Struct({
|
|
494
|
+
...MoveDocumentInput.fields,
|
|
495
|
+
includeChildren: Schema.Boolean
|
|
496
|
+
}).annotate({ identifier: "DuplicateDocumentInput" });
|
|
497
|
+
const UnpublishDocumentInput = Schema.Struct({
|
|
498
|
+
documentId: DocumentId,
|
|
499
|
+
expectedVersion: DocumentVersion,
|
|
500
|
+
...documentMutationMetadata
|
|
501
|
+
}).annotate({ identifier: "UnpublishDocumentInput" });
|
|
258
502
|
const RemoveDocumentInput = Schema.Struct({
|
|
259
503
|
documentId: DocumentId,
|
|
260
504
|
expectedVersion: DocumentVersion,
|
|
@@ -285,9 +529,14 @@ const DOCUMENT_REVISION_ACTIONS = [
|
|
|
285
529
|
"document.update"
|
|
286
530
|
];
|
|
287
531
|
const DocumentRevisionAction = Schema.Literals(DOCUMENT_REVISION_ACTIONS);
|
|
288
|
-
const DocumentMutationAction = Schema.Literals([
|
|
532
|
+
const DocumentMutationAction = Schema.Literals([
|
|
533
|
+
...DOCUMENT_REVISION_ACTIONS,
|
|
534
|
+
"document.publish",
|
|
535
|
+
"document.unpublish"
|
|
536
|
+
]);
|
|
289
537
|
const DocumentMutationResult = Schema.Struct({
|
|
290
538
|
action: DocumentMutationAction,
|
|
539
|
+
affectedDocumentIds: Schema.optionalKey(Schema.Array(DocumentId)),
|
|
291
540
|
documentId: DocumentId,
|
|
292
541
|
generation: DocumentGeneration,
|
|
293
542
|
revisionId: RevisionId,
|
|
@@ -302,5 +551,5 @@ const DocumentValidationResult = Schema.Struct({
|
|
|
302
551
|
}).annotate({ identifier: "DocumentValidationResult" });
|
|
303
552
|
|
|
304
553
|
//#endregion
|
|
305
|
-
export {
|
|
306
|
-
//# sourceMappingURL=models-
|
|
554
|
+
export { MediaName as $, RemoveDocumentInput as A, StudioActor as B, MarkdownNode as C, Slug as Ct, PublishedDocumentPage as D, PublishedDocumentLookup as E, AccessDenied as F, MediaByteSize as G, StudioRequestContext as H, AuthenticationRequired as I, MediaCursor as J, MediaCleanupReport as K, DOCUMENT_ACTIONS as L, UndeleteDocumentInput as M, UnpublishDocumentInput as N, PublishedDocumentQuery as O, UpdateDocumentInput as P, MediaInvalid as Q, MEDIA_ACTIONS as R, DuplicateDocumentInput as S, RevisionNumber as St, PublishDocumentInput as T, nonNegativeInt as Tt, ImageMimeType as U, StudioEntryDenied as V, MediaAsset as W, MediaId as X, MediaFolder as Y, MediaIntegrityReport as Z, DocumentSource as _, DocumentVersion as _t, DOCUMENT_REVISION_ACTIONS as a, MediaReferenced as at, DocumentSurround as b, RelativeDocumentPath as bt, DocumentImportInput as c, MediaUpload as ct, DocumentIssue as d, Locale as dt, MediaNotFound as et, DocumentMutationResult as f, SourceDirectory as ft, DocumentRevisionAction as g, DocumentId as gt, DocumentQueryScalar as h, DocumentHistoryCursor as ht, CreateDocumentInput as i, MediaReference as it, RestoreDocumentInput as j, PublishedDocumentSurroundQuery as k, DocumentImportReport as l, AddressPattern as lt, DocumentNavigationQuery as m, DocumentGeneration as mt, CmsMarkdownDocument as n, MediaPage as nt, DeletedDocument as o, MediaStatus as ot, DocumentNavigationItem as p, RequestId as pt, MediaConflict as q, CompiledDocument as r, MediaQuery as rt, DocumentBrowseQuery as s, MediaTooLarge as st, CmsDocumentAnalysis as t, MediaObjectKey as tt, DocumentImportSource as u, CollectionName as ut, DocumentSourceMapping as v, EditorNodeId as vt, MoveDocumentInput as w, SourcePath as wt, DocumentValidationResult as x, RevisionId as xt, DocumentSummary as y, PublicPath as yt, Role as z };
|
|
555
|
+
//# sourceMappingURL=models-BkMgeaOL.js.map
|