@elytracms/studio 0.0.100 → 0.0.101
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/convex/analytics-cost.test.ts +1 -1
- package/convex/redirect-migration.test.ts +1 -1
- package/convex/redirects.ts +2 -2
- package/convex/shared-capture.convex.test.ts +165 -0
- package/dist/components/ai/ai-chat-panel-lazy.js +7 -2
- package/dist/components/ai/ai-chat-panel-lazy.js.map +1 -1
- package/dist/components/ai/proposal-card.js +2 -1
- package/dist/components/ai/proposal-card.js.map +1 -1
- package/dist/components/ai/proposal-unfilled.d.ts +14 -0
- package/dist/components/ai/proposal-unfilled.js +33 -0
- package/dist/components/ai/proposal-unfilled.js.map +1 -0
- package/dist/components/ai/translate-document-action.js +8 -6
- package/dist/components/ai/translate-document-action.js.map +1 -1
- package/dist/components/app-views/studio-config.d.ts +12 -12
- package/dist/components/app-views/studio-config.js.map +1 -1
- package/dist/components/builder/builder-store.d.ts +37 -1
- package/dist/components/builder/builder-store.js +21 -6
- package/dist/components/builder/builder-store.js.map +1 -1
- package/dist/components/builder/canvas-chrome-css.d.ts +1 -1
- package/dist/components/builder/canvas-chrome-css.js +1 -1
- package/dist/components/builder/canvas-chrome-css.js.map +1 -1
- package/dist/components/builder/canvas-chrome.d.ts +1 -1
- package/dist/components/builder/canvas-chrome.js +1 -1
- package/dist/components/builder/canvas-chrome.js.map +1 -1
- package/dist/components/builder/canvas-rebase.d.ts +4 -4
- package/dist/components/builder/canvas-rebase.js +3 -2
- package/dist/components/builder/canvas-rebase.js.map +1 -1
- package/dist/components/builder/canvas-render-context.d.ts +1 -1
- package/dist/components/builder/canvas-render-context.js +1 -1
- package/dist/components/builder/canvas-render-context.js.map +1 -1
- package/dist/components/builder/composition-field-editor-lazy.js +2 -1
- package/dist/components/builder/composition-field-editor-lazy.js.map +1 -1
- package/dist/components/builder/reuse-context.d.ts +8 -2
- package/dist/components/builder/reuse-context.js +62 -7
- package/dist/components/builder/reuse-context.js.map +1 -1
- package/dist/components/builder/reuse.d.ts +106 -70
- package/dist/components/builder/reuse.js +125 -108
- package/dist/components/builder/reuse.js.map +1 -1
- package/dist/components/cms/cms-store.d.ts +9 -1
- package/dist/components/cms/cms-store.js +1 -0
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/detail-editor.js +13 -13
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/prop-fields.js +1 -1
- package/dist/components/cms/prop-fields.js.map +1 -1
- package/dist/components/cms/rich-text/lazy.js +2 -1
- package/dist/components/cms/rich-text/lazy.js.map +1 -1
- package/dist/components/cms/rich-text/toolbar-state.d.ts +1 -1
- package/dist/components/cms/rich-text/toolbar-state.js +1 -1
- package/dist/components/cms/rich-text/toolbar-state.js.map +1 -1
- package/dist/components/cms/use-field-focus.js +3 -3
- package/dist/components/cms/use-field-focus.js.map +1 -1
- package/dist/components/cms/version-compare-lazy.js +2 -1
- package/dist/components/cms/version-compare-lazy.js.map +1 -1
- package/dist/components/components/components-index.js +1 -1
- package/dist/components/components/components-index.js.map +1 -1
- package/dist/components/deployment-setup-gate.d.ts +1 -1
- package/dist/components/deployment-setup-gate.js +1 -1
- package/dist/components/deployment-setup-gate.js.map +1 -1
- package/dist/components/load-failure.d.ts +62 -0
- package/dist/components/load-failure.js +110 -0
- package/dist/components/load-failure.js.map +1 -0
- package/dist/components/notifications/shell-findings.js +3 -3
- package/dist/components/notifications/shell-findings.js.map +1 -1
- package/dist/customization.d.ts +3 -3
- package/dist/customization.js.map +1 -1
- package/dist/lib/ai/apply-content.js +99 -28
- package/dist/lib/ai/apply-content.js.map +1 -1
- package/dist/lib/ai/chat-context.d.ts +73 -7
- package/dist/lib/ai/chat-context.js +133 -14
- package/dist/lib/ai/chat-context.js.map +1 -1
- package/dist/lib/ai/chat-state.d.ts +7 -1
- package/dist/lib/ai/chat-state.js.map +1 -1
- package/dist/lib/ai/constraints.d.ts +5 -0
- package/dist/lib/ai/constraints.js +21 -6
- package/dist/lib/ai/constraints.js.map +1 -1
- package/dist/lib/ai/fake-provider.d.ts +76 -26
- package/dist/lib/ai/fake-provider.js +210 -66
- package/dist/lib/ai/fake-provider.js.map +1 -1
- package/dist/lib/ai/index.d.ts +1 -0
- package/dist/lib/ai/index.js +1 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/keyless-assistant.d.ts +37 -0
- package/dist/lib/ai/keyless-assistant.js +193 -0
- package/dist/lib/ai/keyless-assistant.js.map +1 -0
- package/dist/lib/ai/shape.d.ts +25 -2
- package/dist/lib/ai/shape.js +58 -7
- package/dist/lib/ai/shape.js.map +1 -1
- package/dist/lib/ai/tools.d.ts +11 -1
- package/dist/lib/ai/tools.js +51 -6
- package/dist/lib/ai/tools.js.map +1 -1
- package/dist/lib/ai/translate-document.js +6 -5
- package/dist/lib/ai/translate-document.js.map +1 -1
- package/dist/lib/ai/types.d.ts +22 -7
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/ai/update-fields.js +9 -6
- package/dist/lib/ai/update-fields.js.map +1 -1
- package/dist/lib/ai/writer-form.d.ts +11 -3
- package/dist/lib/ai/writer-form.js +105 -18
- package/dist/lib/ai/writer-form.js.map +1 -1
- package/dist/lib/auth-errors.d.ts +1 -1
- package/dist/lib/auth-errors.js +1 -1
- package/dist/lib/auth-errors.js.map +1 -1
- package/dist/lib/engine-version.d.ts +1 -1
- package/dist/lib/engine-version.js +1 -1
- package/dist/lib/engine-version.js.map +1 -1
- package/dist/lib/i18n/messages.de.d.ts +1 -1
- package/dist/lib/i18n/messages.de.js +23 -7
- package/dist/lib/i18n/messages.de.js.map +1 -1
- package/dist/lib/i18n/messages.en.d.ts +18 -3
- package/dist/lib/i18n/messages.en.js +29 -9
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/operations/cms-persistence.d.ts +18 -0
- package/dist/lib/operations/cms-persistence.js +47 -0
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/workspace/index.d.ts +3 -3
- package/dist/lib/workspace/index.js +3 -3
- package/dist/lib/workspace/index.js.map +1 -1
- package/dist/router/navigate-once.d.ts +1 -1
- package/dist/router/navigate-once.js.map +1 -1
- package/dist/router/root.d.ts +3 -2
- package/dist/router/root.js +25 -4
- package/dist/router/root.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer-form.js","sourceRoot":"","sources":["../../../src/lib/ai/writer-form.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * **THE AI writer-form converter pair** (EC-593, owner-ratified 2026-10-24 — EC-565\n * Round 4, 4c / 4e / 2c; closes EC-571, EC-562 and EC-570 #3).\n *\n * What a model WRITES is not what is stored: rich text is a markdown string, an asset a\n * bare library id (or its envelope when the position declares placement sub-fields), a\n * relation `{ collection, id }`. Every AI writer — create (`applyContentWithShape`), edit\n * (`buildUpdateProposal`), translate (`translateDocument`) — and the one AI reader\n * (`getDocument`'s output) cross that line here, and only here:\n *\n * - {@link fromWriterForm} — writer form → stored form at a position and EVERY position\n * below it;\n * - {@link toWriterForm} — stored form → the form the model reads (rich text as markdown\n * wherever it is faithfully expressible), at every position.\n *\n * Both are folds over core's ONE value-position traversal (`childPositions` /\n * `rebuildFromChildren`, EC-582): an object's sub-fields, each repeater item, an asset\n * placement's sub-fields, and every DECLARED prop of every component node inside a\n * `blocks` / `richText` value (top level, typography, slots — and below a prop). So a\n * nested position is converted by the same rule as a top-level one; there is no second\n * walk to forget a depth (the bug class EC-571 measured: create converted at every depth,\n * edit at the top level only, the read form and translate at the top level only).\n *\n * At every position the converter applies:\n * - **the id leash** (EC-381) — a relation or asset id must come from what the model\n * searched ({@link WriterLeash}, asked per position: a relation by its target, an asset\n * by its declaration's `accept`) or be one the document already references. Anything\n * else is REMOVED from the value and reported as a `leash` problem (create drops it,\n * edit refuses — the callers' ratified policies);\n * - **the placement carry** (EC-558, ratified 2c) — an asset swap keeps the placement's\n * per-use sub-fields through core's one rule (`carryAssetPlacements`), read from the\n * `current` value the caller passes: the DISPLAYED value of the bucket being written\n * (a new locale bucket carries from its fallback, as the pickers do);\n * - **the composition leash** (ratified 4c) — the AI writes content at every depth and\n * never composition STRUCTURE: a `blocks` value is never written whole\n * (`FIELD_TYPES.blocks.writer === 'composition'`), and a rich-text value must keep the\n * component nodes it holds (same ids, same components, same places). A component's\n * PROP is content — {@link fromWriterFormAtNode} changes one, by its node, at any depth\n * the traversal reaches.\n *\n * Pure and deterministic; no provider, no I/O.\n */\nimport {\n carryAssetPlacements,\n childPositions,\n fieldPath,\n fieldTypeOf,\n fieldValuePosition,\n isSequenceValue,\n rebuildFromChildren,\n referenceNode,\n sequenceComponentNodes,\n walkReferences,\n walkValuePositions,\n} from '@elytracms/core/cms-core'\nimport type {\n AssetFieldDef,\n CmsDocument,\n CollectionDef,\n FieldDef,\n FieldValues,\n PropFieldLookup,\n RelationFieldDef,\n ValuePath,\n ValuePosition,\n} from '@elytracms/core/cms-core'\nimport { parseRichTextValue, richTextValueToMarkdownProse } from '@elytracms/core/rich-text'\nimport { richTextValueFromModelInput } from './rich-text-input'\nimport type { WriterLeash } from './types'\n\n// --- The context ---------------------------------------------------------------------\n\n/** The ids a document already references — reusable anywhere in it without a search. */\nexport interface HeldReferences {\n /** Referenced document ids, by collection. */\n readonly documents: ReadonlyMap<string, ReadonlySet<string>>\n readonly assets: ReadonlySet<string>\n}\n\nexport const NO_HELD_REFERENCES: HeldReferences = { documents: new Map(), assets: new Set() }\n\n/**\n * Every document and asset id a document references, read off THE reference walk\n * (EC-589) — at any depth. An id the document already holds is real (the leash exists\n * so a model cannot INVENT one), so it stays usable at any position without a search.\n */\nexport function heldReferencesOf(document: CmsDocument | undefined): HeldReferences {\n if (!document) return NO_HELD_REFERENCES\n const documents = new Map<string, Set<string>>()\n const assets = new Set<string>()\n walkReferences(document, (hit) => {\n if (hit.target.type === 'asset') assets.add(hit.target.id)\n else if (hit.target.type === 'document') {\n const ids = documents.get(hit.target.ref.collection) ?? new Set<string>()\n ids.add(hit.target.ref.id)\n documents.set(hit.target.ref.collection, ids)\n }\n })\n return { documents, assets }\n}\n\nexport interface WriterFormContext {\n /**\n * Component id → prop field-defs — the validator's own lookup\n * (`validateOptions.lookupManifest`, the canonical bag's), so the converter reaches\n * exactly the props the validator judges. Without it a composition has no prop\n * positions (and {@link fromWriterFormAtNode} refuses, loudly).\n */\n readonly lookupManifest?: PropFieldLookup\n /** What the model searched (absent → no searched ids). */\n readonly leash?: WriterLeash\n /** What the document already references ({@link heldReferencesOf}). */\n readonly held?: HeldReferences\n}\n\n/** One problem the conversion found, located at its position below the field value. */\nexport interface WriterFormProblem {\n /** Index-bearing location below the field value (`ValuePosition.at`). */\n readonly at: readonly (string | number)[]\n readonly code: 'invalid-field-value' | 'unknown-asset' | 'unknown-relation-target'\n readonly message: string\n /** An id outside the leash: it was REMOVED from the converted value. */\n readonly leash?: true\n}\n\nexport interface FromWriterFormResult {\n /** The stored form (`undefined` — clear the position). */\n readonly value: unknown\n readonly problems: readonly WriterFormProblem[]\n}\n\n// --- Writer form → stored form -------------------------------------------------------\n\n/**\n * Convert a value a model authored at `position` (its `value` is the WRITER form) into\n * the stored form, at that position and every position below it. `current` is the value\n * the write replaces — the DISPLAYED value of the bucket being written (ratified 2c) —\n * which the placement carry and the composition leash read. `null` / `undefined` clears.\n */\nexport function fromWriterForm(\n position: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n): FromWriterFormResult {\n const problems: WriterFormProblem[] = []\n const value = convert(position, current, ctx, problems, position.field.name)\n return { value, problems }\n}\n\n/** {@link fromWriterForm} for a top-level field's value. */\nexport function fromWriterFieldValue(\n field: FieldDef,\n raw: unknown,\n current: unknown,\n ctx: WriterFormContext,\n locale?: string,\n): FromWriterFormResult {\n return fromWriterForm(fieldValuePosition(field, raw, locale !== undefined ? { locale } : {}), current, ctx)\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** `title`, `card.image`, `menu[2].label`, `body.content[0].props.headline` — for messages. */\nfunction label(root: string, at: readonly (string | number)[]): string {\n return at.reduce<string>((out, key) => (typeof key === 'number' ? `${out}[${key}]` : `${out}.${key}`), root)\n}\n\n/** The model-facing name of a position: the field's own name, located when nested. */\nfunction subject(pos: ValuePosition, root: string): string {\n return pos.at.length === 0 ? `\"${pos.field.name}\"` : `\"${pos.field.name}\" (at ${label(root, pos.at)})`\n}\n\n/**\n * The structural fingerprint of a composition: which component nodes there are, nested\n * where (their component-ancestor chain), in order relative to each other. Prose between\n * them is content (a new paragraph before an embed shifts its index, not its place among\n * the components); adding, removing, re-nesting or reordering a component is structure.\n */\nfunction compositionOf(value: unknown): string {\n return sequenceComponentNodes(value)\n .map(({ node, chain }) => `${[...chain, node.id].join('/')}=${node.componentId}`)\n .join('|')\n}\n\n/** Key-order-insensitive JSON — \"is this the same value\" for a composition the writer may not change. */\nfunction canonicalJson(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'undefined'\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`\n return `{${Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`)\n .join(',')}}`\n}\n\n/** The stable key matching a child position of the written value to the current value's. */\nfunction childKey(parent: ValuePosition, child: ValuePosition): string {\n // A prop by its node (ids are stable across a prose edit that shifts indices);\n // everything else by its location relative to the parent.\n return child.kind === 'prop' && child.component\n ? `node:${child.component.nodeId}:${child.field.name}`\n : `at:${JSON.stringify(child.at.slice(parent.at.length))}`\n}\n\n/** Convert every child position of `pos` (its value already in a readable shape). */\nfunction convertChildren(\n pos: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n problems: WriterFormProblem[],\n root: string,\n): unknown {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const currentChildren = new Map<string, unknown>()\n if (current !== undefined) {\n for (const child of childPositions({ ...pos, value: current }, positionCtx)) {\n currentChildren.set(childKey(pos, child), child.value)\n }\n }\n return rebuildFromChildren(pos, positionCtx, (child) =>\n convert(child, currentChildren.get(childKey(pos, child)), ctx, problems, root),\n )\n}\n\nfunction convert(\n pos: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n problems: WriterFormProblem[],\n root: string,\n): unknown {\n const { field } = pos\n const raw = pos.value === null ? undefined : pos.value\n const report = (code: WriterFormProblem['code'], message: string, leash?: true): undefined => {\n problems.push({ at: pos.at, code, message, ...(leash ? { leash } : {}) })\n return undefined\n }\n\n switch (fieldTypeOf(field).writer) {\n case 'composition': {\n // 4c: a composition is never written whole — the value stays exactly what it is\n // (re-sending it unchanged is no change); its props change one at a time.\n if (canonicalJson(raw) === canonicalJson(current)) return current\n return report(\n 'invalid-field-value',\n `Field ${subject(pos, root)} is a page-builder composition: adding, reordering or removing its components is done on the canvas, not by the assistant. Change one component's prop with blockId + prop (the component's id from getDocument).`,\n )\n }\n\n case 'markdown': {\n let next: unknown = undefined\n if (raw !== undefined) {\n const parsed = richTextValueFromModelInput(raw)\n if (!parsed.ok) return report('invalid-field-value', `Field ${subject(pos, root)}: ${parsed.problems.join(' ')}`)\n // An echoed stored value may carry components: their props are positions too.\n next = convertChildren({ ...pos, value: parsed.value }, current, ctx, problems, root)\n }\n // 4c: prose is content, the components embedded in it are structure.\n if (compositionOf(next) !== compositionOf(current)) {\n return report(\n 'invalid-field-value',\n `Field ${subject(pos, root)} holds embedded components; the assistant cannot add, remove or move them (that is done in the editor). Send the value back as the stored { version: 2, content } object with every component node kept in place, or change a component's prop with blockId + prop.`,\n )\n }\n return next\n }\n\n case 'placement': {\n if (raw === undefined) return undefined\n const asset = field as AssetFieldDef\n const items = Array.isArray(raw) ? raw : [raw]\n const entries: { id: string; rest: Record<string, unknown> }[] = []\n for (const item of items) {\n if (typeof item === 'string' && item.length > 0) entries.push({ id: item, rest: {} })\n else if (\n isPlainRecord(item) &&\n typeof item.id === 'string' &&\n item.id.length > 0 &&\n (item.type === undefined || item.type === 'asset')\n ) {\n const { type: _type, id, ...rest } = item\n entries.push({ id: id as string, rest })\n } else {\n return report(\n 'invalid-field-value',\n `Asset field ${subject(pos, root)} takes asset id string(s) from listAssets results.`,\n )\n }\n }\n if (asset.multiple !== true && entries.length > 1) {\n return report('invalid-field-value', `Field ${subject(pos, root)} holds a single asset — pass one id.`)\n }\n // EC-381: the asset id leash — searched (fitting this position's `accept`) or\n // already on the document; the assistant never invents or uploads an asset.\n const allowed = new Set([\n ...(ctx.leash?.assetCandidates(asset) ?? []).map((candidate) => candidate.id),\n ...(ctx.held?.assets ?? []),\n ])\n const unknown = entries.filter((entry) => !allowed.has(entry.id))\n if (unknown.length > 0) {\n report(\n 'unknown-asset',\n `Asset field ${subject(pos, root)} may only use ids from listAssets results — search the media library first (got: ${unknown.map((e) => e.id).join(', ')}).`,\n true,\n )\n }\n const kept = entries.filter((entry) => allowed.has(entry.id))\n if (kept.length === 0) return undefined\n // EC-558 / 2c: the ONE carry rule — a held placement keeps its per-use sub-fields,\n // a swap carries them to the new image, a new id is an envelope.\n const carried = carryAssetPlacements(\n current,\n asset.multiple === true ? { multiple: true, ids: kept.map((e) => e.id) } : { multiple: false, id: kept[0]!.id },\n )\n // The writer's own sub-field values win over the carried ones.\n const withWriter = (entry: unknown, index: number): unknown => {\n const rest = kept[index]?.rest ?? {}\n if (Object.keys(rest).length === 0) return entry\n const base = isPlainRecord(entry) ? entry : { type: 'asset', id: kept[index]!.id }\n return { ...base, ...rest }\n }\n const merged = Array.isArray(carried) ? carried.map(withWriter) : withWriter(carried, 0)\n return convertChildren({ ...pos, value: merged }, carried, ctx, problems, root)\n }\n\n case 'reference': {\n if (raw === undefined) return undefined\n const relation = field as RelationFieldDef\n const items = Array.isArray(raw) ? raw : [raw]\n const ids: string[] = []\n for (const item of items) {\n const id = typeof item === 'string' ? item : isPlainRecord(item) && typeof item.id === 'string' ? item.id : undefined\n const collection = isPlainRecord(item) ? item.collection : undefined\n if (!id || (collection !== undefined && collection !== relation.target)) {\n return report(\n 'invalid-field-value',\n `Relation ${subject(pos, root)} takes document id string(s) from searchDocuments results.`,\n )\n }\n ids.push(id)\n }\n if (relation.multiple !== true && ids.length > 1) {\n return report('invalid-field-value', `Field ${subject(pos, root)} holds a single reference — pass one id.`)\n }\n // EC-378/EC-381: the relation id leash — searched in the target collection, or\n // already referenced by the document.\n const allowed = new Set([\n ...(ctx.leash?.relationCandidates(relation.target) ?? []).map((candidate) => candidate.id),\n ...(ctx.held?.documents.get(relation.target) ?? []),\n ])\n const unknown = ids.filter((id) => !allowed.has(id))\n if (unknown.length > 0) {\n report(\n 'unknown-relation-target',\n `Relation ${subject(pos, root)} may only use ids from searchDocuments results — search \"${relation.target}\" first (got: ${unknown.join(', ')}).`,\n true,\n )\n }\n const refs = ids.filter((id) => allowed.has(id)).map((id) => referenceNode({ collection: relation.target, id }))\n if (refs.length === 0) return undefined\n return relation.multiple === true ? refs : refs[0]\n }\n\n case 'object':\n // A value of the wrong shape has no children; the validator names it.\n return raw === undefined ? undefined : convertChildren({ ...pos, value: raw }, current, ctx, problems, root)\n\n case 'value':\n return raw\n }\n}\n\n// --- A component prop, by its node ---------------------------------------------------\n\nexport type FromWriterFormAtNodeResult =\n | {\n readonly ok: true\n /** The field's next value (the displayed value with the one prop converted). */\n readonly value: unknown\n /**\n * The position the change wrote, in the value-position grammar: the prop by its\n * node path where the grammar reaches it, else the coarsest addressable ancestor\n * — the field (bucket) itself (EC-595: a writer may always emit a coarser path).\n */\n readonly path: ValuePath\n /** The converted prop value when {@link path} is the prop itself (`undefined` — unset). */\n readonly propValue: unknown\n readonly exact: boolean\n readonly problems: readonly WriterFormProblem[]\n }\n | { readonly ok: false; readonly message: string }\n\n/**\n * Change ONE component prop, addressed by its node id and prop name, inside a field's\n * value — at ANY depth the traversal reaches: a top-level block, a child in a section's\n * slot, a component embedded in rich text, a component inside an object's rich text or\n * inside another component's prop. The prop's writer form goes through\n * {@link fromWriterForm} with the prop's current value (carry + leash at that position),\n * and the field value is rebuilt by the traversal's writing fold. Nothing else in the\n * value changes — no other prop, no node, no prose.\n */\nexport function fromWriterFormAtNode(\n field: FieldDef,\n displayed: unknown,\n nodeId: string,\n prop: string,\n raw: unknown,\n ctx: WriterFormContext,\n locale?: string,\n): FromWriterFormAtNodeResult {\n if (!ctx.lookupManifest) {\n return {\n ok: false,\n message: `Component props cannot be changed here: the project's components are not available to judge \"${prop}\".`,\n }\n }\n const positionCtx = { lookupManifest: ctx.lookupManifest }\n const root = fieldValuePosition(field, displayed, locale !== undefined ? { locale } : {})\n const isTarget = (position: ValuePosition) =>\n position.kind === 'prop' && position.component?.nodeId === nodeId && position.field.name === prop\n let target: ValuePosition | undefined\n const declared: string[] = []\n let componentId: string | undefined\n walkValuePositions(root, positionCtx, (position) => {\n if (position.kind !== 'prop' || position.component?.nodeId !== nodeId) return\n componentId = position.component.componentId\n declared.push(position.field.name)\n if (target === undefined && position.field.name === prop) target = position\n })\n if (!target) {\n if (componentId === undefined) {\n return {\n ok: false,\n message: `Component \"${nodeId}\" was not found in \"${field.name}\" (or its component declares no props) — read the document first; component ids come from getDocument.`,\n }\n }\n return {\n ok: false,\n message: `Component \"${nodeId}\" (${componentId}) has no prop \"${prop}\" — its props are: ${declared.join(', ')}.`,\n }\n }\n const found = target\n const { value: converted, problems } = fromWriterForm({ ...found, value: raw }, found.value, ctx)\n const rebuild = (position: ValuePosition): unknown =>\n rebuildFromChildren(position, positionCtx, (child) => (isTarget(child) ? converted : rebuild(child)))\n const value = rebuild(root)\n return found.exact\n ? { ok: true, value, path: found.path, propValue: converted, exact: true, problems }\n : { ok: true, value, path: fieldPath(field.name, locale), propValue: undefined, exact: false, problems }\n}\n\n// --- The text positions (translate) --------------------------------------------------\n\n/** Whether a field-def holds TEXT a translation turns into units: plain text, or a sequence. */\nexport function isTextPosition(position: ValuePosition): boolean {\n const { type } = position.field\n return type === 'text' || type === 'richText' || type === 'blocks'\n}\n\nfunction isExcludedBelow(position: ValuePosition): boolean {\n return position.at.length > 0 && position.field.ai?.exclude === true\n}\n\n/**\n * Every TEXT position at or below `position` (EC-593, ratified 4e — \"translate uses the\n * same traversal\"): a `text` value, and a `richText` / `blocks` sequence (its prose —\n * the sequence's own text — is the caller's to split) together with every text position\n * below it: component text props in a composition and in rich-text embeds, object\n * sub-fields, repeater items, asset placement sub-fields. An `ai.exclude` position (and\n * everything below it) is not text a writer may touch. Depth-first, document order.\n */\nexport function textPositionsOf(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): ValuePosition[] {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const out: ValuePosition[] = []\n const visit = (current: ValuePosition): void => {\n if (isExcludedBelow(current)) return\n if (isTextPosition(current)) out.push(current)\n if (current.field.type === 'text') return\n for (const child of childPositions(current, positionCtx)) visit(child)\n }\n visit(position)\n return out\n}\n\n/**\n * The writing fold over {@link textPositionsOf}: the value at `position` with each text\n * position's value replaced by `replace(textPosition)` — for a sequence, its own value\n * first (its prose), then the text positions below it, read off the REPLACED value (a\n * component keeps its node id, so its props are found again). Every other value — an\n * image, a select, a component's structure — comes back as it was (identity-preserving).\n */\nexport function rebuildTextPositions(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n replace: (textPosition: ValuePosition) => unknown,\n): unknown {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const rebuild = (current: ValuePosition): unknown => {\n if (isExcludedBelow(current)) return current.value\n if (current.field.type === 'text') return replace(current)\n const value = isTextPosition(current) ? replace(current) : current.value\n return rebuildFromChildren({ ...current, value }, positionCtx, rebuild)\n }\n return rebuild(position)\n}\n\n// --- Stored form → the read (writer) form --------------------------------------------\n\n/**\n * The form a model READS a stored value in — the mirror of {@link fromWriterForm}, so\n * what `getDocument` shows is what `updateFields` takes back: rich text as a markdown\n * string wherever the engine's loss-guarded inverse can express it faithfully (no\n * embedded components, subset-only marks — else the stored `{ version: 2, content }`\n * stays, so nothing echoed back can silently lose structure), at EVERY position: a\n * top-level field, an object sub-field, a repeater item, a component's rich-text prop.\n * Everything else reads as stored (envelopes are writer forms too).\n */\nexport function toWriterForm(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): unknown {\n const { value } = position\n if (value === undefined || value === null) return value\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n if (fieldTypeOf(position.field).writer === 'markdown' && isSequenceValue(value)) {\n const parsed = parseRichTextValue(value)\n const markdown = parsed.ok ? richTextValueToMarkdownProse(parsed.value) : undefined\n if (markdown !== undefined) return markdown\n }\n return rebuildFromChildren(position, positionCtx, (child) => toWriterForm(child, ctx))\n}\n\n/**\n * The components a document holds whose props a writer may change — every component\n * the traversal reaches a DECLARED prop of, in every field of every bucket, at any depth\n * — in first-seen order. What the `getDocument` output's prop catalog lists.\n */\nexport function componentIdsOf(\n collection: CollectionDef,\n document: CmsDocument,\n lookupManifest: PropFieldLookup,\n): string[] {\n const ids = new Set<string>()\n const byName = new Map(collection.fields.map((field) => [field.name, field]))\n const visitBucket = (bucket: FieldValues) => {\n for (const [name, value] of Object.entries(bucket)) {\n const field = byName.get(name)\n if (!field) continue\n walkValuePositions(fieldValuePosition(field, value), { lookupManifest }, (position) => {\n if (position.kind === 'prop' && position.component) ids.add(position.component.componentId)\n })\n }\n }\n visitBucket(document.values)\n for (const bucket of Object.values(document.localized ?? {})) visitBucket(bucket)\n return [...ids]\n}\n\n/** {@link toWriterForm} over every field of every bucket of a document. */\nexport function toWriterDocument(\n collection: CollectionDef,\n document: CmsDocument,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): CmsDocument {\n const byName = new Map(collection.fields.map((field) => [field.name, field]))\n const mapBucket = (bucket: FieldValues, locale?: string): FieldValues => {\n let next = bucket\n for (const [name, value] of Object.entries(bucket)) {\n const field = byName.get(name)\n if (!field) continue\n const read = toWriterForm(fieldValuePosition(field, value, locale !== undefined ? { locale } : {}), ctx)\n if (read === value) continue\n if (next === bucket) next = { ...bucket }\n next[name] = read\n }\n return next\n }\n const values = mapBucket(document.values)\n const localized = document.localized\n ? Object.fromEntries(Object.entries(document.localized).map(([locale, bucket]) => [locale, mapBucket(bucket, locale)]))\n : undefined\n return { ...document, values, ...(localized ? { localized } : {}) }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"writer-form.js","sourceRoot":"","sources":["../../../src/lib/ai/writer-form.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * **THE AI writer-form converter pair** (EC-593, owner-ratified 2026-10-24 — EC-565\n * Round 4, 4c / 4e / 2c; closes EC-571, EC-562 and EC-570 #3).\n *\n * What a model WRITES is not what is stored: rich text is a markdown string, an asset a\n * bare library id (or its envelope when the position declares placement sub-fields), a\n * relation `{ collection, id }`. Every AI writer — create (`applyContentWithShape`), edit\n * (`buildUpdateProposal`), translate (`translateDocument`) — and the one AI reader\n * (`getDocument`'s output) cross that line here, and only here:\n *\n * - {@link fromWriterForm} — writer form → stored form at a position and EVERY position\n * below it;\n * - {@link toWriterForm} — stored form → the form the model reads (rich text as markdown\n * wherever it is faithfully expressible), at every position.\n *\n * Both are folds over core's ONE value-position traversal (`childPositions` /\n * `rebuildFromChildren`, EC-582): an object's sub-fields, each repeater item, an asset\n * placement's sub-fields, and every DECLARED prop of every component node inside a\n * `blocks` / `richText` value (top level, typography, slots — and below a prop). So a\n * nested position is converted by the same rule as a top-level one; there is no second\n * walk to forget a depth (the bug class EC-571 measured: create converted at every depth,\n * edit at the top level only, the read form and translate at the top level only).\n *\n * At every position the converter applies:\n * - **the id leash** (EC-381) — a relation or asset id must come from what the model\n * searched ({@link WriterLeash}, asked per position: a relation by its target, an asset\n * by its declaration's `accept`) or be one the document already references. Anything\n * else is REMOVED from the value and reported as a `leash` problem (create drops it,\n * edit refuses — the callers' ratified policies);\n * - **the placement carry** (EC-558, ratified 2c) — an asset swap keeps the placement's\n * per-use sub-fields through core's one rule (`carryAssetPlacements`), read from the\n * `current` value the caller passes: the DISPLAYED value of the bucket being written\n * (a new locale bucket carries from its fallback, as the pickers do);\n * - **the composition leash** (ratified 4c) — the AI writes content at every depth and\n * never composition STRUCTURE: a `blocks` value is never written whole\n * (`FIELD_TYPES.blocks.writer === 'composition'`), and a rich-text value must keep the\n * component nodes it holds (same ids, same components, same places). A component's\n * PROP is content — {@link fromWriterFormAtNode} changes one, by its node, at any depth\n * the traversal reaches;\n * - **the writer lock** (EC-716, owner ruling \"Yes, honour readOnly\") — a position core's\n * `writerLockOf` locks (`ai.exclude` or `form.readOnly`, and everything below it) keeps\n * its CURRENT value. Leaving it out of the written value, or echoing it back unchanged,\n * is no write; any other value is reported as a `locked` problem (create drops it, edit\n * refuses — the same two policies as the id leash).\n *\n * Pure and deterministic; no provider, no I/O.\n */\nimport {\n carryAssetPlacements,\n childPositions,\n fieldPath,\n fieldTypeOf,\n fieldValuePosition,\n isSequenceValue,\n rebuildFromChildren,\n referenceNode,\n seedObjectItem,\n sequenceComponentNodes,\n walkReferences,\n walkValuePositions,\n writerLockOf,\n} from '@elytracms/core/cms-core'\nimport type {\n AssetFieldDef,\n CmsDocument,\n CollectionDef,\n FieldDef,\n FieldValues,\n PropFieldLookup,\n RelationFieldDef,\n ValuePath,\n ValuePosition,\n WriterLock,\n} from '@elytracms/core/cms-core'\nimport { parseRichTextValue, richTextValueToMarkdownProse } from '@elytracms/core/rich-text'\nimport { richTextValueFromModelInput } from './rich-text-input'\nimport type { WriterLeash } from './types'\n\n// --- The context ---------------------------------------------------------------------\n\n/** The ids a document already references — reusable anywhere in it without a search. */\nexport interface HeldReferences {\n /** Referenced document ids, by collection. */\n readonly documents: ReadonlyMap<string, ReadonlySet<string>>\n readonly assets: ReadonlySet<string>\n}\n\nexport const NO_HELD_REFERENCES: HeldReferences = { documents: new Map(), assets: new Set() }\n\n/**\n * Every document and asset id a document references, read off THE reference walk\n * (EC-589) — at any depth. An id the document already holds is real (the leash exists\n * so a model cannot INVENT one), so it stays usable at any position without a search.\n */\nexport function heldReferencesOf(document: CmsDocument | undefined): HeldReferences {\n if (!document) return NO_HELD_REFERENCES\n const documents = new Map<string, Set<string>>()\n const assets = new Set<string>()\n walkReferences(document, (hit) => {\n if (hit.target.type === 'asset') assets.add(hit.target.id)\n else if (hit.target.type === 'document') {\n const ids = documents.get(hit.target.ref.collection) ?? new Set<string>()\n ids.add(hit.target.ref.id)\n documents.set(hit.target.ref.collection, ids)\n }\n })\n return { documents, assets }\n}\n\nexport interface WriterFormContext {\n /**\n * Component id → prop field-defs — the validator's own lookup\n * (`validateOptions.lookupManifest`, the canonical bag's), so the converter reaches\n * exactly the props the validator judges. Without it a composition has no prop\n * positions (and {@link fromWriterFormAtNode} refuses, loudly).\n */\n readonly lookupManifest?: PropFieldLookup\n /** What the model searched (absent → no searched ids). */\n readonly leash?: WriterLeash\n /** What the document already references ({@link heldReferencesOf}). */\n readonly held?: HeldReferences\n}\n\n/** One problem the conversion found, located at its position below the field value. */\nexport interface WriterFormProblem {\n /** Index-bearing location below the field value (`ValuePosition.at`). */\n readonly at: readonly (string | number)[]\n readonly code: 'invalid-field-value' | 'unknown-asset' | 'unknown-relation-target'\n readonly message: string\n /** An id outside the leash: it was REMOVED from the converted value. */\n readonly leash?: true\n /** A write to a writer-locked position (EC-716): the position KEPT its current value. */\n readonly locked?: true\n}\n\n/**\n * What a writer is told about a write to a locked position (EC-716) — one wording for the\n * create's dropped-value warning, the edit's refusal and a component prop's refusal.\n */\nexport function lockedWriteMessage(subjectText: string, lock: WriterLock): string {\n return lock === 'excluded'\n ? `${subjectText} must not be edited by the assistant.`\n : `${subjectText} is read-only — no one changes it in the studio, the assistant included.`\n}\n\nexport interface FromWriterFormResult {\n /** The stored form (`undefined` — clear the position). */\n readonly value: unknown\n readonly problems: readonly WriterFormProblem[]\n}\n\n// --- Writer form → stored form -------------------------------------------------------\n\n/**\n * Convert a value a model authored at `position` (its `value` is the WRITER form) into\n * the stored form, at that position and every position below it. `current` is the value\n * the write replaces — the DISPLAYED value of the bucket being written (ratified 2c) —\n * which the placement carry and the composition leash read. `null` / `undefined` clears.\n */\nexport function fromWriterForm(\n position: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n): FromWriterFormResult {\n const problems: WriterFormProblem[] = []\n const value = convert(position, current, ctx, problems, position.field.name)\n return { value, problems }\n}\n\n/** {@link fromWriterForm} for a top-level field's value. */\nexport function fromWriterFieldValue(\n field: FieldDef,\n raw: unknown,\n current: unknown,\n ctx: WriterFormContext,\n locale?: string,\n): FromWriterFormResult {\n return fromWriterForm(fieldValuePosition(field, raw, locale !== undefined ? { locale } : {}), current, ctx)\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** `title`, `card.image`, `menu[2].label`, `body.content[0].props.headline` — for messages. */\nfunction label(root: string, at: readonly (string | number)[]): string {\n return at.reduce<string>((out, key) => (typeof key === 'number' ? `${out}[${key}]` : `${out}.${key}`), root)\n}\n\n/** The model-facing name of a position: the field's own name, located when nested. */\nfunction subject(pos: ValuePosition, root: string): string {\n return pos.at.length === 0 ? `\"${pos.field.name}\"` : `\"${pos.field.name}\" (at ${label(root, pos.at)})`\n}\n\n/**\n * The structural fingerprint of a composition: which component nodes there are, nested\n * where (their component-ancestor chain), in order relative to each other. Prose between\n * them is content (a new paragraph before an embed shifts its index, not its place among\n * the components); adding, removing, re-nesting or reordering a component is structure.\n */\nfunction compositionOf(value: unknown): string {\n return sequenceComponentNodes(value)\n .map(({ node, chain }) => `${[...chain, node.id].join('/')}=${node.componentId}`)\n .join('|')\n}\n\n/** Key-order-insensitive JSON — \"is this the same value\" for a composition the writer may not change. */\nfunction canonicalJson(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'undefined'\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`\n return `{${Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`)\n .join(',')}}`\n}\n\n/** The stable key matching a child position of the written value to the current value's. */\nfunction childKey(parent: ValuePosition, child: ValuePosition): string {\n // A prop by its node (ids are stable across a prose edit that shifts indices);\n // everything else by its location relative to the parent.\n return child.kind === 'prop' && child.component\n ? `node:${child.component.nodeId}:${child.field.name}`\n : `at:${JSON.stringify(child.at.slice(parent.at.length))}`\n}\n\n/** Convert every child position of `pos` (its value already in a readable shape). */\nfunction convertChildren(\n pos: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n problems: WriterFormProblem[],\n root: string,\n): unknown {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const currentChildren = new Map<string, unknown>()\n if (current !== undefined) {\n for (const child of childPositions({ ...pos, value: current }, positionCtx)) {\n currentChildren.set(childKey(pos, child), child.value)\n }\n }\n return rebuildFromChildren(pos, positionCtx, (child) =>\n convert(child, currentChildren.get(childKey(pos, child)), ctx, problems, root),\n )\n}\n\nfunction convert(\n pos: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n problems: WriterFormProblem[],\n root: string,\n): unknown {\n // EC-716: a locked position keeps its current value — and so, by not being visited,\n // does everything below it (the lock cascades as the form's `readOnly` does).\n const lock = writerLockOf(pos.field)\n if (lock === undefined) return convertValue(pos, current, ctx, problems, root)\n if (pos.value === undefined || isEcho(pos, current, ctx, root)) return current\n problems.push({\n at: pos.at,\n code: 'invalid-field-value',\n message: lockedWriteMessage(`Field ${subject(pos, root)}`, lock),\n locked: true,\n })\n return current\n}\n\n/**\n * Whether a value written to a locked position leaves it as it is: a clear of an empty\n * position, or the current value echoed back — as stored, in the form the model READ it\n * in ({@link toWriterForm}: rich text as markdown), or in any writer form that converts to\n * exactly the stored value.\n */\nfunction isEcho(pos: ValuePosition, current: unknown, ctx: WriterFormContext, root: string): boolean {\n const written = pos.value\n if (written === null) return current === undefined || current === null\n if (current === undefined || current === null) return false\n const json = canonicalJson(written)\n if (json === canonicalJson(current)) return true\n if (json === canonicalJson(toWriterForm({ ...pos, value: current }, ctx))) return true\n const scratch: WriterFormProblem[] = []\n const stored = convertValue(pos, current, ctx, scratch, root)\n return scratch.length === 0 && canonicalJson(stored) === canonicalJson(current)\n}\n\n/**\n * A repeater's current value with every item the written list adds seeded the way a\n * manual \"add item\" seeds it (core's `seedObjectItem`), so a locked sub-field of a NEW item\n * keeps its default rather than staying empty (EC-716, sol-C 22 at item level). Items are\n * matched by index — the matching the converter uses for every repeater.\n */\nfunction withSeededItems(current: unknown, length: number, fields: readonly FieldDef[]): unknown {\n const items = Array.isArray(current) ? current : []\n if (items.length >= length) return current\n return [...items, ...Array.from({ length: length - items.length }, () => seedObjectItem(fields))]\n}\n\n/** {@link convert} for a position no lock holds: the writer form → the stored form. */\nfunction convertValue(\n pos: ValuePosition,\n current: unknown,\n ctx: WriterFormContext,\n problems: WriterFormProblem[],\n root: string,\n): unknown {\n const { field } = pos\n const raw = pos.value === null ? undefined : pos.value\n const report = (code: WriterFormProblem['code'], message: string, leash?: true): undefined => {\n problems.push({ at: pos.at, code, message, ...(leash ? { leash } : {}) })\n return undefined\n }\n\n switch (fieldTypeOf(field).writer) {\n case 'composition': {\n // 4c: a composition is never written whole — the value stays exactly what it is\n // (re-sending it unchanged is no change); its props change one at a time.\n if (canonicalJson(raw) === canonicalJson(current)) return current\n return report(\n 'invalid-field-value',\n `Field ${subject(pos, root)} is a page-builder composition: adding, reordering or removing its components is done on the canvas, not by the assistant. Change one component's prop with blockId + prop (the component's id from getDocument).`,\n )\n }\n\n case 'markdown': {\n let next: unknown = undefined\n if (raw !== undefined) {\n const parsed = richTextValueFromModelInput(raw)\n if (!parsed.ok) return report('invalid-field-value', `Field ${subject(pos, root)}: ${parsed.problems.join(' ')}`)\n // An echoed stored value may carry components: their props are positions too.\n next = convertChildren({ ...pos, value: parsed.value }, current, ctx, problems, root)\n }\n // 4c: prose is content, the components embedded in it are structure.\n if (compositionOf(next) !== compositionOf(current)) {\n return report(\n 'invalid-field-value',\n `Field ${subject(pos, root)} holds embedded components; the assistant cannot add, remove or move them (that is done in the editor). Send the value back as the stored { version: 2, content } object with every component node kept in place, or change a component's prop with blockId + prop.`,\n )\n }\n return next\n }\n\n case 'placement': {\n if (raw === undefined) return undefined\n const asset = field as AssetFieldDef\n const items = Array.isArray(raw) ? raw : [raw]\n const entries: { id: string; rest: Record<string, unknown> }[] = []\n for (const item of items) {\n if (typeof item === 'string' && item.length > 0) entries.push({ id: item, rest: {} })\n else if (\n isPlainRecord(item) &&\n typeof item.id === 'string' &&\n item.id.length > 0 &&\n (item.type === undefined || item.type === 'asset')\n ) {\n const { type: _type, id, ...rest } = item\n entries.push({ id: id as string, rest })\n } else {\n return report(\n 'invalid-field-value',\n `Asset field ${subject(pos, root)} takes asset id string(s) from listAssets results.`,\n )\n }\n }\n if (asset.multiple !== true && entries.length > 1) {\n return report('invalid-field-value', `Field ${subject(pos, root)} holds a single asset — pass one id.`)\n }\n // EC-381: the asset id leash — searched (fitting this position's `accept`) or\n // already on the document; the assistant never invents or uploads an asset.\n const allowed = new Set([\n ...(ctx.leash?.assetCandidates(asset) ?? []).map((candidate) => candidate.id),\n ...(ctx.held?.assets ?? []),\n ])\n const unknown = entries.filter((entry) => !allowed.has(entry.id))\n if (unknown.length > 0) {\n report(\n 'unknown-asset',\n `Asset field ${subject(pos, root)} may only use ids from listAssets results — search the media library first (got: ${unknown.map((e) => e.id).join(', ')}).`,\n true,\n )\n }\n const kept = entries.filter((entry) => allowed.has(entry.id))\n if (kept.length === 0) return undefined\n // EC-558 / 2c: the ONE carry rule — a held placement keeps its per-use sub-fields,\n // a swap carries them to the new image, a new id is an envelope.\n const carried = carryAssetPlacements(\n current,\n asset.multiple === true ? { multiple: true, ids: kept.map((e) => e.id) } : { multiple: false, id: kept[0]!.id },\n )\n // The writer's own sub-field values win over the carried ones.\n const withWriter = (entry: unknown, index: number): unknown => {\n const rest = kept[index]?.rest ?? {}\n if (Object.keys(rest).length === 0) return entry\n const base = isPlainRecord(entry) ? entry : { type: 'asset', id: kept[index]!.id }\n return { ...base, ...rest }\n }\n const merged = Array.isArray(carried) ? carried.map(withWriter) : withWriter(carried, 0)\n return convertChildren({ ...pos, value: merged }, carried, ctx, problems, root)\n }\n\n case 'reference': {\n if (raw === undefined) return undefined\n const relation = field as RelationFieldDef\n const items = Array.isArray(raw) ? raw : [raw]\n const ids: string[] = []\n for (const item of items) {\n const id = typeof item === 'string' ? item : isPlainRecord(item) && typeof item.id === 'string' ? item.id : undefined\n const collection = isPlainRecord(item) ? item.collection : undefined\n if (!id || (collection !== undefined && collection !== relation.target)) {\n return report(\n 'invalid-field-value',\n `Relation ${subject(pos, root)} takes document id string(s) from searchDocuments results.`,\n )\n }\n ids.push(id)\n }\n if (relation.multiple !== true && ids.length > 1) {\n return report('invalid-field-value', `Field ${subject(pos, root)} holds a single reference — pass one id.`)\n }\n // EC-378/EC-381: the relation id leash — searched in the target collection, or\n // already referenced by the document.\n const allowed = new Set([\n ...(ctx.leash?.relationCandidates(relation.target) ?? []).map((candidate) => candidate.id),\n ...(ctx.held?.documents.get(relation.target) ?? []),\n ])\n const unknown = ids.filter((id) => !allowed.has(id))\n if (unknown.length > 0) {\n report(\n 'unknown-relation-target',\n `Relation ${subject(pos, root)} may only use ids from searchDocuments results — search \"${relation.target}\" first (got: ${unknown.join(', ')}).`,\n true,\n )\n }\n const refs = ids.filter((id) => allowed.has(id)).map((id) => referenceNode({ collection: relation.target, id }))\n if (refs.length === 0) return undefined\n return relation.multiple === true ? refs : refs[0]\n }\n\n case 'object': {\n // A value of the wrong shape has no children; the validator names it.\n if (raw === undefined) return undefined\n const base =\n field.type === 'object' && field.multiple && Array.isArray(raw)\n ? withSeededItems(current, raw.length, field.fields)\n : current\n return convertChildren({ ...pos, value: raw }, base, ctx, problems, root)\n }\n\n case 'value':\n return raw\n }\n}\n\n// --- A component prop, by its node ---------------------------------------------------\n\nexport type FromWriterFormAtNodeResult =\n | {\n readonly ok: true\n /** The field's next value (the displayed value with the one prop converted). */\n readonly value: unknown\n /**\n * The position the change wrote, in the value-position grammar: the prop by its\n * node path where the grammar reaches it, else the coarsest addressable ancestor\n * — the field (bucket) itself (EC-595: a writer may always emit a coarser path).\n */\n readonly path: ValuePath\n /** The converted prop value when {@link path} is the prop itself (`undefined` — unset). */\n readonly propValue: unknown\n readonly exact: boolean\n readonly problems: readonly WriterFormProblem[]\n }\n | { readonly ok: false; readonly message: string }\n\n/**\n * Change ONE component prop, addressed by its node id and prop name, inside a field's\n * value — at ANY depth the traversal reaches: a top-level block, a child in a section's\n * slot, a component embedded in rich text, a component inside an object's rich text or\n * inside another component's prop. The prop's writer form goes through\n * {@link fromWriterForm} with the prop's current value (carry + leash at that position),\n * and the field value is rebuilt by the traversal's writing fold. Nothing else in the\n * value changes — no other prop, no node, no prose.\n */\nexport function fromWriterFormAtNode(\n field: FieldDef,\n displayed: unknown,\n nodeId: string,\n prop: string,\n raw: unknown,\n ctx: WriterFormContext,\n locale?: string,\n): FromWriterFormAtNodeResult {\n if (!ctx.lookupManifest) {\n return {\n ok: false,\n message: `Component props cannot be changed here: the project's components are not available to judge \"${prop}\".`,\n }\n }\n const positionCtx = { lookupManifest: ctx.lookupManifest }\n const root = fieldValuePosition(field, displayed, locale !== undefined ? { locale } : {})\n const isTarget = (position: ValuePosition) =>\n position.kind === 'prop' && position.component?.nodeId === nodeId && position.field.name === prop\n let target: ValuePosition | undefined\n // EC-716: the lock the target sits under — its own, or the nearest locked ancestor's\n // (a component embedded in a read-only rich-text prop, a prop of a locked object…).\n let targetLock: WriterLock | undefined\n const declared: string[] = []\n let componentId: string | undefined\n const visit = (position: ValuePosition, inherited: WriterLock | undefined): void => {\n const lock = writerLockOf(position.field) ?? inherited\n if (position.kind === 'prop' && position.component?.nodeId === nodeId) {\n componentId = position.component.componentId\n declared.push(position.field.name)\n if (target === undefined && position.field.name === prop) {\n target = position\n targetLock = lock\n }\n }\n for (const child of childPositions(position, positionCtx)) visit(child, lock)\n }\n visit(root, undefined)\n if (target && targetLock !== undefined) {\n return {\n ok: false,\n message: lockedWriteMessage(`Prop \"${prop}\" of component \"${nodeId}\" (${componentId})`, targetLock),\n }\n }\n if (!target) {\n if (componentId === undefined) {\n return {\n ok: false,\n message: `Component \"${nodeId}\" was not found in \"${field.name}\" (or its component declares no props) — read the document first; component ids come from getDocument.`,\n }\n }\n return {\n ok: false,\n message: `Component \"${nodeId}\" (${componentId}) has no prop \"${prop}\" — its props are: ${declared.join(', ')}.`,\n }\n }\n const found = target\n const { value: converted, problems } = fromWriterForm({ ...found, value: raw }, found.value, ctx)\n const rebuild = (position: ValuePosition): unknown =>\n rebuildFromChildren(position, positionCtx, (child) => (isTarget(child) ? converted : rebuild(child)))\n const value = rebuild(root)\n return found.exact\n ? { ok: true, value, path: found.path, propValue: converted, exact: true, problems }\n : { ok: true, value, path: fieldPath(field.name, locale), propValue: undefined, exact: false, problems }\n}\n\n// --- The text positions (translate) --------------------------------------------------\n\n/** Whether a field-def holds TEXT a translation turns into units: plain text, or a sequence. */\nexport function isTextPosition(position: ValuePosition): boolean {\n const { type } = position.field\n return type === 'text' || type === 'richText' || type === 'blocks'\n}\n\n/** EC-716: a writer-locked position — no unit, no write, nothing below it either. */\nfunction isLocked(position: ValuePosition): boolean {\n return writerLockOf(position.field) !== undefined\n}\n\n/**\n * Every TEXT position at or below `position` (EC-593, ratified 4e — \"translate uses the\n * same traversal\"): a `text` value, and a `richText` / `blocks` sequence (its prose —\n * the sequence's own text — is the caller's to split) together with every text position\n * below it: component text props in a composition and in rich-text embeds, object\n * sub-fields, repeater items, asset placement sub-fields. A writer-locked position\n * (EC-716: `ai.exclude` or `form.readOnly`) and everything below it is not text a writer\n * may touch — not a unit, and so never a skip either. Depth-first, document order.\n */\nexport function textPositionsOf(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): ValuePosition[] {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const out: ValuePosition[] = []\n const visit = (current: ValuePosition): void => {\n if (isLocked(current)) return\n if (isTextPosition(current)) out.push(current)\n if (current.field.type === 'text') return\n for (const child of childPositions(current, positionCtx)) visit(child)\n }\n visit(position)\n return out\n}\n\n/**\n * The writing fold over {@link textPositionsOf}: the value at `position` with each text\n * position's value replaced by `replace(textPosition)` — for a sequence, its own value\n * first (its prose), then the text positions below it, read off the REPLACED value (a\n * component keeps its node id, so its props are found again). Every other value — an\n * image, a select, a component's structure — comes back as it was (identity-preserving).\n */\nexport function rebuildTextPositions(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n replace: (textPosition: ValuePosition) => unknown,\n): unknown {\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n const rebuild = (current: ValuePosition): unknown => {\n if (isLocked(current)) return current.value\n if (current.field.type === 'text') return replace(current)\n const value = isTextPosition(current) ? replace(current) : current.value\n return rebuildFromChildren({ ...current, value }, positionCtx, rebuild)\n }\n return rebuild(position)\n}\n\n// --- Stored form → the read (writer) form --------------------------------------------\n\n/**\n * The form a model READS a stored value in — the mirror of {@link fromWriterForm}, so\n * what `getDocument` shows is what `updateFields` takes back: rich text as a markdown\n * string wherever the engine's loss-guarded inverse can express it faithfully (no\n * embedded components, subset-only marks — else the stored `{ version: 2, content }`\n * stays, so nothing echoed back can silently lose structure), at EVERY position: a\n * top-level field, an object sub-field, a repeater item, a component's rich-text prop.\n * Everything else reads as stored (envelopes are writer forms too).\n */\nexport function toWriterForm(\n position: ValuePosition,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): unknown {\n const { value } = position\n if (value === undefined || value === null) return value\n const positionCtx = ctx.lookupManifest ? { lookupManifest: ctx.lookupManifest } : {}\n if (fieldTypeOf(position.field).writer === 'markdown' && isSequenceValue(value)) {\n const parsed = parseRichTextValue(value)\n const markdown = parsed.ok ? richTextValueToMarkdownProse(parsed.value) : undefined\n if (markdown !== undefined) return markdown\n }\n return rebuildFromChildren(position, positionCtx, (child) => toWriterForm(child, ctx))\n}\n\n/**\n * The components a document holds whose props a writer may change — every component\n * the traversal reaches a DECLARED prop of, in every field of every bucket, at any depth\n * — in first-seen order. What the `getDocument` output's prop catalog lists.\n */\nexport function componentIdsOf(\n collection: CollectionDef,\n document: CmsDocument,\n lookupManifest: PropFieldLookup,\n): string[] {\n const ids = new Set<string>()\n const byName = new Map(collection.fields.map((field) => [field.name, field]))\n const visitBucket = (bucket: FieldValues) => {\n for (const [name, value] of Object.entries(bucket)) {\n const field = byName.get(name)\n if (!field) continue\n walkValuePositions(fieldValuePosition(field, value), { lookupManifest }, (position) => {\n if (position.kind === 'prop' && position.component) ids.add(position.component.componentId)\n })\n }\n }\n visitBucket(document.values)\n for (const bucket of Object.values(document.localized ?? {})) visitBucket(bucket)\n return [...ids]\n}\n\n/** {@link toWriterForm} over every field of every bucket of a document. */\nexport function toWriterDocument(\n collection: CollectionDef,\n document: CmsDocument,\n ctx: Pick<WriterFormContext, 'lookupManifest'>,\n): CmsDocument {\n const byName = new Map(collection.fields.map((field) => [field.name, field]))\n const mapBucket = (bucket: FieldValues, locale?: string): FieldValues => {\n let next = bucket\n for (const [name, value] of Object.entries(bucket)) {\n const field = byName.get(name)\n if (!field) continue\n const read = toWriterForm(fieldValuePosition(field, value, locale !== undefined ? { locale } : {}), ctx)\n if (read === value) continue\n if (next === bucket) next = { ...bucket }\n next[name] = read\n }\n return next\n }\n const values = mapBucket(document.values)\n const localized = document.localized\n ? Object.fromEntries(Object.entries(document.localized).map(([locale, bucket]) => [locale, mapBucket(bucket, locale)]))\n : undefined\n return { ...document, values, ...(localized ? { localized } : {}) }\n}\n"]}
|
|
@@ -30,7 +30,7 @@ type SignInFailure = Extract<SignInResult, {
|
|
|
30
30
|
* catalog key that carries each of those messages, so the sign-in screen
|
|
31
31
|
* localizes failures through the SAME catalog as the rest of the chrome
|
|
32
32
|
* (a German catalog covers them with no consumer-side mapper — the
|
|
33
|
-
* pre-EC-375
|
|
33
|
+
* pre-EC-375 consumer-side `authErrorMessage` is retired by this seam).
|
|
34
34
|
*
|
|
35
35
|
* A reason can carry several distinct engine messages (`unavailable` spans
|
|
36
36
|
* the rate-limit, the honest server-error generic, and the playground
|
package/dist/lib/auth-errors.js
CHANGED
|
@@ -75,7 +75,7 @@ export function isSessionExpiredError(error) {
|
|
|
75
75
|
* catalog key that carries each of those messages, so the sign-in screen
|
|
76
76
|
* localizes failures through the SAME catalog as the rest of the chrome
|
|
77
77
|
* (a German catalog covers them with no consumer-side mapper — the
|
|
78
|
-
* pre-EC-375
|
|
78
|
+
* pre-EC-375 consumer-side `authErrorMessage` is retired by this seam).
|
|
79
79
|
*
|
|
80
80
|
* A reason can carry several distinct engine messages (`unavailable` spans
|
|
81
81
|
* the rate-limit, the honest server-error generic, and the playground
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-errors.js","sourceRoot":"","sources":["../../src/lib/auth-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChangePasswordResult, SignInResult, UpdateProfileResult } from './auth/auth-adapter'\nimport { isUnauthenticatedTransportText } from './auth/convex-auth-adapter'\nimport { EN_MESSAGES } from './i18n/messages.en'\nimport type { OperationError } from './operations'\n\n/**\n * Session-expiry detection + plain-language mapping (EC-177 gap 9).\n *\n * An expired Convex session surfaces as a raw backend blob thrown by the\n * transport — e.g. `{\"code\":\"Unauthenticated\",\"message\":\"Could not verify\n * OIDC token claim…\"}` — which `toOperationError` can only normalize to an\n * `unknown`/`backend-unavailable` `OperationError` whose message *is* that\n * blob. Rendering it verbatim is editor-hostile, and the real problem (edits\n * silently stop persisting) is invisible.\n *\n * This module is the one chokepoint that recognizes that shape on the\n * structured `OperationError` (the seam every studio failure already flows\n * through), so UI surfaces never string-match raw messages themselves. Since\n * EC-403 an expired session is an app-level state: `lib/session-expiry.ts`\n * runs this predicate over every failed operation on the lifecycle bus and\n * raises the blocking in-place re-auth overlay (the\n * `error.sessionExpiredTitle` / `error.sessionExpired` catalog keys) — the\n * shared banner only uses it to route expiry AWAY from per-surface rendering.\n */\n\n/**\n * Extract the `code` of a JSON object embedded in a transport error message.\n * Convex auth failures carry `{\"code\":\"Unauthenticated\", …}`, sometimes\n * wrapped in client prefixes (`[CONVEX M(graph:save)] … Server Error: {…}`).\n */\nfunction embeddedJsonCode(message: string): string | undefined {\n const start = message.indexOf('{')\n const end = message.lastIndexOf('}')\n if (start === -1 || end <= start) return undefined\n try {\n const parsed: unknown = JSON.parse(message.slice(start, end + 1))\n if (parsed !== null && typeof parsed === 'object') {\n const code = (parsed as { code?: unknown }).code\n if (typeof code === 'string') return code\n }\n } catch {\n // Not a JSON payload — fall through to the marker checks.\n }\n return undefined\n}\n\n/**\n * Does this operation failure mean \"the session is no longer valid\"?\n *\n * Only the transport-shaped codes can carry the backend auth blob: structured\n * studio-level failures (`validation`, `unauthorized` from the role hook,\n * `not-found`, `conflict`) are never session expiry. Within those, detect the\n * Convex unauthenticated shape: an embedded `{\"code\":\"Unauthenticated\"}`\n * payload, or the SAME positive-rejection markers the EC-415 probe classifier\n * ({@link isUnauthenticatedTransportText}, `lib/auth/convex-auth-adapter.ts`)\n * pins — the bare `Unauthenticated` server-error marker, the OIDC claim\n * message it ships with, and (EC-427) `InvalidAuthHeader`: the backend\n * positively rejecting a malformed/unverifiable token, not just an\n * expired-claims one. Reusing that one exported classifier (rather than a\n * second copy of the regex ladder here) is the drift guard — the probe and\n * this reactive predicate can never recognize a different set of real 401\n * bodies (`lib/auth-errors.test.ts` proves agreement over every pinned\n * fixture). `lib/auth/**` itself is untouched: the classifier was already\n * exported for this reuse.\n */\nexport function isSessionExpiredError(error: OperationError): boolean {\n if (error.code !== 'unknown' && error.code !== 'backend-unavailable') return false\n if (embeddedJsonCode(error.message) === 'Unauthenticated') return true\n return isUnauthenticatedTransportText(error.message)\n}\n\ntype SignInFailure = Extract<SignInResult, { ok: false }>\n\n/**\n * Engine-owned sign-in-failure → message-catalog-key mapping (EC-397). The\n * auth adapters (no-touch `lib/auth/**`) return plain-English `message`\n * constants on the EC-362/EC-363 classified reasons; this table names the\n * catalog key that carries each of those messages, so the sign-in screen\n * localizes failures through the SAME catalog as the rest of the chrome\n * (a German catalog covers them with no consumer-side mapper — the\n * pre-EC-375 Naturkinder `authErrorMessage` is retired by this seam).\n *\n * A reason can carry several distinct engine messages (`unavailable` spans\n * the rate-limit, the honest server-error generic, and the playground\n * sign-up refusal), so each reason lists its candidate keys and a failure is\n * recognized by **exact EN-message match** against the catalog entry. That\n * makes English rendering byte-identical by construction and keeps the\n * fallback honest: any unrecognized message (a future reason, a reworded\n * adapter constant, a non-engine adapter) falls through to the raw\n * `result.message` — never a mistranslated or stale mapping.\n * `lib/auth-errors.test.ts` runs the real classifier over every branch to\n * pin that adapter copy and catalog never drift apart silently.\n */\nexport const SIGN_IN_ERROR_KEYS: Record<SignInFailure['reason'], readonly string[]> = {\n 'invalid-credentials': [\n 'auth.signIn.error.invalidCredentials',\n 'auth.signIn.error.invalidCredentialsSignUp',\n ],\n 'account-exists': ['auth.signIn.error.accountExists'],\n 'deployment-misconfigured': ['auth.signIn.error.deploymentMisconfigured'],\n 'not-invited': ['auth.signIn.error.notInvited'],\n unavailable: [\n 'auth.signIn.error.tooManyAttempts',\n 'auth.signIn.error.serverError',\n 'auth.signIn.error.serverErrorSignUp',\n 'auth.signIn.error.unavailable',\n 'auth.signIn.error.playgroundSignUp',\n ],\n}\n\n/**\n * Resolve a failure `{ reason, message }` against a reason → candidate-keys\n * table by **exact EN-message match** (the EC-397 recognition rule): the\n * matched key's catalog entry carries the same English, so EN rendering stays\n * byte-identical, and anything unrecognized returns `null` — the caller\n * renders the raw message, never a stale mapping.\n */\nfunction errorMessageKey(\n table: Record<string, readonly string[] | undefined>,\n failure: { reason: string; message: string },\n): string | null {\n const candidates = table[failure.reason]\n return candidates?.find((key) => EN_MESSAGES[key]?.message === failure.message) ?? null\n}\n\n/**\n * Resolve a failed {@link SignInResult} to its message-catalog key, or `null`\n * when the failure is not an engine-known shape (render `result.message` raw\n * — the honest fallback). Pure; accepts the failure structurally so callers\n * and tests can probe unknown future reasons without casts.\n */\nexport function signInErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(SIGN_IN_ERROR_KEYS, failure)\n}\n\ntype ChangePasswordFailure = Extract<ChangePasswordResult, { ok: false }>\n\n/**\n * Engine-owned change-password-failure → message-catalog-key mapping (EC-412)\n * — the {@link SIGN_IN_ERROR_KEYS} design extended to the account credential\n * panel. The reasons are the {@link ChangePasswordResult} failure union;\n * `unavailable` again spans several deliberate messages (the\n * deployment-misconfigured remedy, the EC-377 rate limit, and the honest\n * server-error generic), so recognition is by reason + exact EN-message match\n * and every unrecognized shape falls through to the raw `result.message`.\n * `lib/auth-errors.test.ts` runs the real `classifyChangePasswordError` over\n * every branch to pin adapter copy and catalog together.\n */\nexport const CHANGE_PASSWORD_ERROR_KEYS: Record<\n ChangePasswordFailure['reason'],\n readonly string[]\n> = {\n 'invalid-credentials': ['account.password.error.currentIncorrect'],\n 'weak-password': ['account.password.error.weakPassword'],\n 'not-authenticated': ['account.password.error.notSignedIn'],\n unavailable: [\n 'account.password.error.deploymentMisconfigured',\n 'account.password.error.tooManyAttempts',\n 'account.password.error.serverError',\n ],\n unsupported: ['account.password.error.playgroundUnsupported'],\n}\n\n/**\n * Resolve a failed {@link ChangePasswordResult} to its message-catalog key, or\n * `null` when the failure is not an engine-known shape (render\n * `result.message` raw — the honest fallback).\n */\nexport function changePasswordErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(CHANGE_PASSWORD_ERROR_KEYS, failure)\n}\n\ntype UpdateProfileFailure = Extract<UpdateProfileResult, { ok: false }>\n\n/**\n * Engine-owned update-profile-failure → message-catalog-key mapping (EC-416) —\n * the {@link SIGN_IN_ERROR_KEYS} / {@link CHANGE_PASSWORD_ERROR_KEYS} design\n * extended to the account identity form (`self-account-view-source.ts`'s\n * `save`, which calls `AuthAdapter.updateProfile`). The reasons are the\n * {@link UpdateProfileResult} failure union. Unlike change-password,\n * `updateProfile` is NOT richly classified: the `users:updateProfile` Convex\n * mutation never throws a coded `ConvexError`, so `ConvexAuthAdapter` collapses\n * every failure (missing `users:me` row, thrown mutation error, network\n * failure) into one generic `unavailable` message — there is no\n * `classifyUpdateProfileError` to extend, and adding one would mean editing the\n * no-touch `lib/auth/**` mutation to throw coded errors, which is out of scope\n * here.\n *\n * `not-authenticated` reuses `account.password.error.notSignedIn` rather than\n * a new key: `ConvexAuthAdapter.updateProfile` and `.changePassword` both\n * return the byte-identical constant `'You are not signed in.'` for a missing\n * token, so a second key would only duplicate the same English (and German)\n * copy under a different name.\n */\nexport const UPDATE_PROFILE_ERROR_KEYS: Record<UpdateProfileFailure['reason'], readonly string[]> = {\n 'not-authenticated': ['account.password.error.notSignedIn'],\n unavailable: ['account.profile.error.unavailable'],\n unsupported: ['account.profile.error.playgroundUnsupported'],\n}\n\n/**\n * Resolve a failed {@link UpdateProfileResult} to its message-catalog key, or\n * `null` when the failure is not an engine-known shape (render\n * `result.message` raw — the honest fallback).\n */\nexport function updateProfileErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(UPDATE_PROFILE_ERROR_KEYS, failure)\n}\n\n// `signInHref` (the banner's navigating \"Sign in again\" action) was retired by\n// EC-403: re-auth happens in place via the blocking overlay — a navigation\n// would destroy exactly the unsaved editor state the treatment protects.\n"]}
|
|
1
|
+
{"version":3,"file":"auth-errors.js","sourceRoot":"","sources":["../../src/lib/auth-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChangePasswordResult, SignInResult, UpdateProfileResult } from './auth/auth-adapter'\nimport { isUnauthenticatedTransportText } from './auth/convex-auth-adapter'\nimport { EN_MESSAGES } from './i18n/messages.en'\nimport type { OperationError } from './operations'\n\n/**\n * Session-expiry detection + plain-language mapping (EC-177 gap 9).\n *\n * An expired Convex session surfaces as a raw backend blob thrown by the\n * transport — e.g. `{\"code\":\"Unauthenticated\",\"message\":\"Could not verify\n * OIDC token claim…\"}` — which `toOperationError` can only normalize to an\n * `unknown`/`backend-unavailable` `OperationError` whose message *is* that\n * blob. Rendering it verbatim is editor-hostile, and the real problem (edits\n * silently stop persisting) is invisible.\n *\n * This module is the one chokepoint that recognizes that shape on the\n * structured `OperationError` (the seam every studio failure already flows\n * through), so UI surfaces never string-match raw messages themselves. Since\n * EC-403 an expired session is an app-level state: `lib/session-expiry.ts`\n * runs this predicate over every failed operation on the lifecycle bus and\n * raises the blocking in-place re-auth overlay (the\n * `error.sessionExpiredTitle` / `error.sessionExpired` catalog keys) — the\n * shared banner only uses it to route expiry AWAY from per-surface rendering.\n */\n\n/**\n * Extract the `code` of a JSON object embedded in a transport error message.\n * Convex auth failures carry `{\"code\":\"Unauthenticated\", …}`, sometimes\n * wrapped in client prefixes (`[CONVEX M(graph:save)] … Server Error: {…}`).\n */\nfunction embeddedJsonCode(message: string): string | undefined {\n const start = message.indexOf('{')\n const end = message.lastIndexOf('}')\n if (start === -1 || end <= start) return undefined\n try {\n const parsed: unknown = JSON.parse(message.slice(start, end + 1))\n if (parsed !== null && typeof parsed === 'object') {\n const code = (parsed as { code?: unknown }).code\n if (typeof code === 'string') return code\n }\n } catch {\n // Not a JSON payload — fall through to the marker checks.\n }\n return undefined\n}\n\n/**\n * Does this operation failure mean \"the session is no longer valid\"?\n *\n * Only the transport-shaped codes can carry the backend auth blob: structured\n * studio-level failures (`validation`, `unauthorized` from the role hook,\n * `not-found`, `conflict`) are never session expiry. Within those, detect the\n * Convex unauthenticated shape: an embedded `{\"code\":\"Unauthenticated\"}`\n * payload, or the SAME positive-rejection markers the EC-415 probe classifier\n * ({@link isUnauthenticatedTransportText}, `lib/auth/convex-auth-adapter.ts`)\n * pins — the bare `Unauthenticated` server-error marker, the OIDC claim\n * message it ships with, and (EC-427) `InvalidAuthHeader`: the backend\n * positively rejecting a malformed/unverifiable token, not just an\n * expired-claims one. Reusing that one exported classifier (rather than a\n * second copy of the regex ladder here) is the drift guard — the probe and\n * this reactive predicate can never recognize a different set of real 401\n * bodies (`lib/auth-errors.test.ts` proves agreement over every pinned\n * fixture). `lib/auth/**` itself is untouched: the classifier was already\n * exported for this reuse.\n */\nexport function isSessionExpiredError(error: OperationError): boolean {\n if (error.code !== 'unknown' && error.code !== 'backend-unavailable') return false\n if (embeddedJsonCode(error.message) === 'Unauthenticated') return true\n return isUnauthenticatedTransportText(error.message)\n}\n\ntype SignInFailure = Extract<SignInResult, { ok: false }>\n\n/**\n * Engine-owned sign-in-failure → message-catalog-key mapping (EC-397). The\n * auth adapters (no-touch `lib/auth/**`) return plain-English `message`\n * constants on the EC-362/EC-363 classified reasons; this table names the\n * catalog key that carries each of those messages, so the sign-in screen\n * localizes failures through the SAME catalog as the rest of the chrome\n * (a German catalog covers them with no consumer-side mapper — the\n * pre-EC-375 consumer-side `authErrorMessage` is retired by this seam).\n *\n * A reason can carry several distinct engine messages (`unavailable` spans\n * the rate-limit, the honest server-error generic, and the playground\n * sign-up refusal), so each reason lists its candidate keys and a failure is\n * recognized by **exact EN-message match** against the catalog entry. That\n * makes English rendering byte-identical by construction and keeps the\n * fallback honest: any unrecognized message (a future reason, a reworded\n * adapter constant, a non-engine adapter) falls through to the raw\n * `result.message` — never a mistranslated or stale mapping.\n * `lib/auth-errors.test.ts` runs the real classifier over every branch to\n * pin that adapter copy and catalog never drift apart silently.\n */\nexport const SIGN_IN_ERROR_KEYS: Record<SignInFailure['reason'], readonly string[]> = {\n 'invalid-credentials': [\n 'auth.signIn.error.invalidCredentials',\n 'auth.signIn.error.invalidCredentialsSignUp',\n ],\n 'account-exists': ['auth.signIn.error.accountExists'],\n 'deployment-misconfigured': ['auth.signIn.error.deploymentMisconfigured'],\n 'not-invited': ['auth.signIn.error.notInvited'],\n unavailable: [\n 'auth.signIn.error.tooManyAttempts',\n 'auth.signIn.error.serverError',\n 'auth.signIn.error.serverErrorSignUp',\n 'auth.signIn.error.unavailable',\n 'auth.signIn.error.playgroundSignUp',\n ],\n}\n\n/**\n * Resolve a failure `{ reason, message }` against a reason → candidate-keys\n * table by **exact EN-message match** (the EC-397 recognition rule): the\n * matched key's catalog entry carries the same English, so EN rendering stays\n * byte-identical, and anything unrecognized returns `null` — the caller\n * renders the raw message, never a stale mapping.\n */\nfunction errorMessageKey(\n table: Record<string, readonly string[] | undefined>,\n failure: { reason: string; message: string },\n): string | null {\n const candidates = table[failure.reason]\n return candidates?.find((key) => EN_MESSAGES[key]?.message === failure.message) ?? null\n}\n\n/**\n * Resolve a failed {@link SignInResult} to its message-catalog key, or `null`\n * when the failure is not an engine-known shape (render `result.message` raw\n * — the honest fallback). Pure; accepts the failure structurally so callers\n * and tests can probe unknown future reasons without casts.\n */\nexport function signInErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(SIGN_IN_ERROR_KEYS, failure)\n}\n\ntype ChangePasswordFailure = Extract<ChangePasswordResult, { ok: false }>\n\n/**\n * Engine-owned change-password-failure → message-catalog-key mapping (EC-412)\n * — the {@link SIGN_IN_ERROR_KEYS} design extended to the account credential\n * panel. The reasons are the {@link ChangePasswordResult} failure union;\n * `unavailable` again spans several deliberate messages (the\n * deployment-misconfigured remedy, the EC-377 rate limit, and the honest\n * server-error generic), so recognition is by reason + exact EN-message match\n * and every unrecognized shape falls through to the raw `result.message`.\n * `lib/auth-errors.test.ts` runs the real `classifyChangePasswordError` over\n * every branch to pin adapter copy and catalog together.\n */\nexport const CHANGE_PASSWORD_ERROR_KEYS: Record<\n ChangePasswordFailure['reason'],\n readonly string[]\n> = {\n 'invalid-credentials': ['account.password.error.currentIncorrect'],\n 'weak-password': ['account.password.error.weakPassword'],\n 'not-authenticated': ['account.password.error.notSignedIn'],\n unavailable: [\n 'account.password.error.deploymentMisconfigured',\n 'account.password.error.tooManyAttempts',\n 'account.password.error.serverError',\n ],\n unsupported: ['account.password.error.playgroundUnsupported'],\n}\n\n/**\n * Resolve a failed {@link ChangePasswordResult} to its message-catalog key, or\n * `null` when the failure is not an engine-known shape (render\n * `result.message` raw — the honest fallback).\n */\nexport function changePasswordErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(CHANGE_PASSWORD_ERROR_KEYS, failure)\n}\n\ntype UpdateProfileFailure = Extract<UpdateProfileResult, { ok: false }>\n\n/**\n * Engine-owned update-profile-failure → message-catalog-key mapping (EC-416) —\n * the {@link SIGN_IN_ERROR_KEYS} / {@link CHANGE_PASSWORD_ERROR_KEYS} design\n * extended to the account identity form (`self-account-view-source.ts`'s\n * `save`, which calls `AuthAdapter.updateProfile`). The reasons are the\n * {@link UpdateProfileResult} failure union. Unlike change-password,\n * `updateProfile` is NOT richly classified: the `users:updateProfile` Convex\n * mutation never throws a coded `ConvexError`, so `ConvexAuthAdapter` collapses\n * every failure (missing `users:me` row, thrown mutation error, network\n * failure) into one generic `unavailable` message — there is no\n * `classifyUpdateProfileError` to extend, and adding one would mean editing the\n * no-touch `lib/auth/**` mutation to throw coded errors, which is out of scope\n * here.\n *\n * `not-authenticated` reuses `account.password.error.notSignedIn` rather than\n * a new key: `ConvexAuthAdapter.updateProfile` and `.changePassword` both\n * return the byte-identical constant `'You are not signed in.'` for a missing\n * token, so a second key would only duplicate the same English (and German)\n * copy under a different name.\n */\nexport const UPDATE_PROFILE_ERROR_KEYS: Record<UpdateProfileFailure['reason'], readonly string[]> = {\n 'not-authenticated': ['account.password.error.notSignedIn'],\n unavailable: ['account.profile.error.unavailable'],\n unsupported: ['account.profile.error.playgroundUnsupported'],\n}\n\n/**\n * Resolve a failed {@link UpdateProfileResult} to its message-catalog key, or\n * `null` when the failure is not an engine-known shape (render\n * `result.message` raw — the honest fallback).\n */\nexport function updateProfileErrorMessageKey(failure: {\n reason: string\n message: string\n}): string | null {\n return errorMessageKey(UPDATE_PROFILE_ERROR_KEYS, failure)\n}\n\n// `signInHref` (the banner's navigating \"Sign in again\" action) was retired by\n// EC-403: re-auth happens in place via the blocking overlay — a navigation\n// would destroy exactly the unsaved editor state the treatment protects.\n"]}
|
|
@@ -13,4 +13,4 @@
|
|
|
13
13
|
* (The convex-side stamp does NOT read this mirror — `convex/delivery.ts` imports the
|
|
14
14
|
* package.json declaration directly; its bundler allows what tsc's rootDir forbids.)
|
|
15
15
|
*/
|
|
16
|
-
export declare const ENGINE_VERSION = "0.0.
|
|
16
|
+
export declare const ENGINE_VERSION = "0.0.101";
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* (The convex-side stamp does NOT read this mirror — `convex/delivery.ts` imports the
|
|
14
14
|
* package.json declaration directly; its bundler allows what tsc's rootDir forbids.)
|
|
15
15
|
*/
|
|
16
|
-
export const ENGINE_VERSION = '0.0.
|
|
16
|
+
export const ENGINE_VERSION = '0.0.101';
|
|
17
17
|
//# sourceMappingURL=engine-version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-version.js","sourceRoot":"","sources":["../../src/lib/engine-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA","sourcesContent":["/**\n * The engine version this studio build was compiled from (EC-552) — the client-side\n * half of the deployed-functions version handshake: the boot gate compares it against\n * what `delivery:engineVersion` answers from the deployment.\n *\n * A MIRROR of `package.json`'s `version`, not the declaration itself: client source\n * cannot import `../../package.json` (outside the tsc build's `rootDir`; moving the\n * root would reshape `dist` and every export path). The parity test beside this file\n * fs-reads the real declaration and fails `pnpm verify` the moment the two diverge,\n * so a release cannot ship with a stale mirror. `pnpm release:bump` writes this\n * alongside the five `package.json` versions (EC-608).\n *\n * (The convex-side stamp does NOT read this mirror — `convex/delivery.ts` imports the\n * package.json declaration directly; its bundler allows what tsc's rootDir forbids.)\n */\nexport const ENGINE_VERSION = '0.0.
|
|
1
|
+
{"version":3,"file":"engine-version.js","sourceRoot":"","sources":["../../src/lib/engine-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA","sourcesContent":["/**\n * The engine version this studio build was compiled from (EC-552) — the client-side\n * half of the deployed-functions version handshake: the boot gate compares it against\n * what `delivery:engineVersion` answers from the deployment.\n *\n * A MIRROR of `package.json`'s `version`, not the declaration itself: client source\n * cannot import `../../package.json` (outside the tsc build's `rootDir`; moving the\n * root would reshape `dist` and every export path). The parity test beside this file\n * fs-reads the real declaration and fails `pnpm verify` the moment the two diverge,\n * so a release cannot ship with a stale mirror. `pnpm release:bump` writes this\n * alongside the five `package.json` versions (EC-608).\n *\n * (The convex-side stamp does NOT read this mirror — `convex/delivery.ts` imports the\n * package.json declaration directly; its bundler allows what tsc's rootDir forbids.)\n */\nexport const ENGINE_VERSION = '0.0.101'\n"]}
|
|
@@ -8,7 +8,7 @@ import type { TranslationCatalog } from './messages.en.js';
|
|
|
8
8
|
* `{ ...deMessages, 'some.key': 'eigene Formulierung' }`.
|
|
9
9
|
*
|
|
10
10
|
* Seeded 2026-07-15 as the best-of merge of the two hand-maintained consumer
|
|
11
|
-
* catalogs (
|
|
11
|
+
* catalogs (on a conflict, the second consumer's won) + fresh translations for the keys both
|
|
12
12
|
* lacked (incl. EC-397's sign-in/boot copy). Typed against
|
|
13
13
|
* {@link TranslationCatalog} so an unknown/stale key fails typecheck;
|
|
14
14
|
* `messages.de.test.ts` pins EXACT key parity with the EN source (no missing,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* `{ ...deMessages, 'some.key': 'eigene Formulierung' }`.
|
|
8
8
|
*
|
|
9
9
|
* Seeded 2026-07-15 as the best-of merge of the two hand-maintained consumer
|
|
10
|
-
* catalogs (
|
|
10
|
+
* catalogs (on a conflict, the second consumer's won) + fresh translations for the keys both
|
|
11
11
|
* lacked (incl. EC-397's sign-in/boot copy). Typed against
|
|
12
12
|
* {@link TranslationCatalog} so an unknown/stale key fails typecheck;
|
|
13
13
|
* `messages.de.test.ts` pins EXACT key parity with the EN source (no missing,
|
|
@@ -125,6 +125,14 @@ export const deMessages = {
|
|
|
125
125
|
'shell.backToProjects': 'Zurück zu den Projekten',
|
|
126
126
|
'shell.routeNotFound.title': 'Seite nicht gefunden',
|
|
127
127
|
'shell.routeNotFound.body': 'Diese Studio-URL verweist auf keinen Bereich.',
|
|
128
|
+
'shell.failure.module.title': 'Dieser Teil des Studios konnte nicht geladen werden',
|
|
129
|
+
'shell.failure.module.body': 'Sein Code ließ sich nicht herunterladen, meist weil der Dev-Server seinen Abhängigkeits-Cache neu aufgebaut hat, während dieser Tab offen war. Gehen Sie zurück, um weiterzuarbeiten; dieser Teil bleibt bis zum Neuladen der Seite nicht verfügbar.',
|
|
130
|
+
'shell.failure.module.restartHint': 'Hilft Neuladen nicht, starten Sie den Dev-Server neu.',
|
|
131
|
+
'shell.failure.error.title': 'Etwas ist schiefgelaufen',
|
|
132
|
+
'shell.failure.error.body': 'Im Studio ist hier ein unerwarteter Fehler aufgetreten. Neuladen der Seite behebt das meist.',
|
|
133
|
+
'shell.failure.back': 'Zurück',
|
|
134
|
+
'shell.failure.reload': 'Neu laden',
|
|
135
|
+
'shell.failure.reloadCost': 'Neuladen leert den Playground: Alles, was in diesem Tab erstellt oder geändert wurde, geht verloren.',
|
|
128
136
|
'shell.projectSwitcher.recent': 'Zuletzt verwendet',
|
|
129
137
|
'shell.projects': 'Projekte',
|
|
130
138
|
'shell.projectSwitcher.browseAll': 'Alle Projekte durchsuchen',
|
|
@@ -181,13 +189,12 @@ export const deMessages = {
|
|
|
181
189
|
'customization.issue.derivedIdBuiltinCollision': 'Die Ansicht „{label}“ für „{point}“ leitet die id „{id}“ aus ihrer Beschriftung ab, was der eingebauten Ansicht „{id}“ entspricht — die eingebaute Ansicht bleibt erhalten und diese wird ignoriert. Geben Sie eine explizite id an, um eine eingebaute Ansicht absichtlich zu ersetzen.',
|
|
182
190
|
'customization.issue.derivedIdCollectionCollision': 'Die Ansichts-id „{id}“ für „{point}“ ist mehrdeutig: Sie verbindet die Sammlungen {collections} mit „-“, und eine Sammlung heißt buchstäblich „{joined}“ — deren eigene Ansicht leitet dieselbe id ab. Geben Sie dieser Gruppe eine explizite id.',
|
|
183
191
|
// EC-467 — die Deklaration wiederverwendbarer Elemente (`defineStudio({ reuse })`).
|
|
184
|
-
'builder.reuse.config.unknownComponent': 'Wiederverwendbare Elemente: Die Studio-Konfiguration deklariert reuse.component „{component}“, was keine registrierte Komponente ist. Korrigieren Sie die id
|
|
192
|
+
'builder.reuse.config.unknownComponent': 'Wiederverwendbare Elemente: Die Studio-Konfiguration deklariert reuse.component „{component}“, was keine registrierte Komponente ist. Korrigieren Sie die id, sodass sie Ihre Einbettungs-Komponente nennt — bis dahin sind die Wiederverwendungs-Gesten deaktiviert.',
|
|
185
193
|
'builder.reuse.config.noRelationProp': 'Wiederverwendbare Elemente: Die deklarierte Einbettung „{component}“ hat kein Relations-Prop für ein einzelnes Dokument und kann daher auf kein wiederverwendbares Dokument zeigen. Eine Einbettung benötigt genau ein Relations-Prop mit Kardinalität eins.',
|
|
186
194
|
'builder.reuse.config.unknownRelationProp': 'Wiederverwendbare Elemente: Die deklarierte Einbettung „{component}“ hat kein Relations-Prop für ein einzelnes Dokument mit dem Namen „{relationProp}“. Ihre Relations-Props sind: {props}.',
|
|
187
195
|
'builder.reuse.config.ambiguousRelationProp': 'Wiederverwendbare Elemente: Die deklarierte Einbettung „{component}“ hat {count} Relations-Props für ein einzelnes Dokument ({props}) — ergänzen Sie reuse.relationProp, um anzugeben, welches auf das wiederverwendbare Dokument zeigt.',
|
|
188
196
|
'builder.reuse.config.unknownCollection': 'Wiederverwendbare Elemente: „{component}.{relationProp}“ verweist auf die Sammlung „{collection}“, die dieses Projekt nicht definiert.',
|
|
189
197
|
'builder.reuse.config.noBlocksField': 'Wiederverwendbare Elemente: Die Sammlung „{collection}“ hinter „{component}.{relationProp}“ hat kein Block-Feld (Komposition), sodass die Einbettung nichts einbinden kann.',
|
|
190
|
-
'builder.reuse.config.ambiguousInference': 'Wiederverwendbare Elemente: {count} Komponenten haben die Form einer wiederverwendbaren Einbettung ({components}). Ein Projekt hat genau eine wiederverwendbare Einbettung, deshalb rät das Studio nicht — deklarieren Sie sie in studio.config als reuse: { component: \'<id>\' }. Bis dahin sind die Wiederverwendungs-Gesten deaktiviert.',
|
|
191
198
|
// ─────────────────────────────────────────────────────────────────────────
|
|
192
199
|
// Auth / errors
|
|
193
200
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -564,7 +571,7 @@ export const deMessages = {
|
|
|
564
571
|
'cms.issueMessage.relationStrictUnpublished': 'Das Beziehungsfeld „{field}“ ist strikt: „{id}“ in „{target}“ ist nicht veröffentlicht — dieses Dokument kann erst veröffentlicht werden, wenn es veröffentlicht ist.',
|
|
565
572
|
'cms.issueMessage.assetNoAssetCollection': 'Das Medienfeld „{field}“ benötigt eine Mediensammlung, es ist aber keine registriert.',
|
|
566
573
|
'cms.issueMessage.assetSingleValued': 'Das Medienfeld „{field}“ ist einwertig, hat aber {count} Ziele.',
|
|
567
|
-
'cms.issueMessage.assetExpectsId':
|
|
574
|
+
'cms.issueMessage.assetExpectsId': "Das Medienfeld „{field}“ erwartet eine Medien-id oder { type: 'asset', id, …Felder je Verwendung } — ein Objekt braucht type: 'asset'.",
|
|
568
575
|
'cms.issueMessage.assetUnknown': 'Das Medienfeld „{field}“ verweist auf das unbekannte Medium „{asset}“.',
|
|
569
576
|
'cms.issueMessage.assetNotAccepted': 'Das Medienfeld „{field}“ akzeptiert nur {accept}, das Medium „{asset}“ ist aber {type}.',
|
|
570
577
|
'cms.issueMessage.requiredFieldMissing': 'Das Pflichtfeld „{field}“ fehlt.',
|
|
@@ -1010,10 +1017,10 @@ export const deMessages = {
|
|
|
1010
1017
|
'components.index.byCategory': 'Nach Kategorie',
|
|
1011
1018
|
'components.index.guide.title': 'Projektkomponenten registrieren',
|
|
1012
1019
|
'components.index.guide.badge': 'Anleitung',
|
|
1013
|
-
'components.index.guide.intro': 'Komponenten sind Code und gehören Ihrem Repository. Registrieren Sie ein Manifest mit Eigenschaftsschemata, Standardwerten, Inspektor-Steuerelementen, Slots und Vorschauzuständen. Das Studio kann die Komponente anschließend durchsuchen, prüfen und anzeigen. Diese Anleitungen im
|
|
1020
|
+
'components.index.guide.intro': 'Komponenten sind Code und gehören Ihrem Repository. Registrieren Sie ein Manifest mit Eigenschaftsschemata, Standardwerten, Inspektor-Steuerelementen, Slots und Vorschauzuständen. Das Studio kann die Komponente anschließend durchsuchen, prüfen und anzeigen. Diese Anleitungen im docs-Ordner des Elytra-Engine-Repositorys erklären die Einzelheiten:',
|
|
1014
1021
|
'components.index.guide.doc.authoring': 'So deklarieren und registrieren Sie eine Komponente, damit das Studio sie durchsuchen, prüfen und anzeigen kann.',
|
|
1015
|
-
'components.index.guide.doc.
|
|
1016
|
-
'components.index.guide.doc.
|
|
1022
|
+
'components.index.guide.doc.components': 'Das Komponenten-Kapitel der Anleitung: Manifest und Implementierung als Paar, die Liste registrieren, Vorschauzustände, wiederverwendbare Elemente, Gestaltung.',
|
|
1023
|
+
'components.index.guide.doc.guide': 'Überblick und Kapitelverzeichnis der Anleitung: Einrichtung, Konfigurations-API, Auslieferung, CLI- und Umgebungsreferenz.',
|
|
1017
1024
|
'components.index.guide.namespaceNote': 'Komponenten sind die Liste in Ihrer Konfiguration, mit IDs Ihrer Wahl (Heading, site.Hero). Elytras eigene Komponenten sind das optionale Paket @elytracms/components — alle, eine Auswahl oder keine.',
|
|
1018
1025
|
'components.taxonomy.uncategorized': 'Ohne Kategorie',
|
|
1019
1026
|
'components.detail.tab.preview': 'Vorschau',
|
|
@@ -1129,6 +1136,11 @@ export const deMessages = {
|
|
|
1129
1136
|
'builder.reuse.madeReusablePublished': '„{name}“ wiederverwendbar gemacht und veröffentlicht.',
|
|
1130
1137
|
'builder.reuse.madeReusablePublishFailed': '„{name}“ wiederverwendbar gemacht, aber die Veröffentlichung ist fehlgeschlagen — veröffentlichen Sie es aus seinem Dokument.',
|
|
1131
1138
|
'builder.reuse.madeReusableDraft': '„{name}“ wiederverwendbar gemacht (Entwurf) — veröffentlichen Sie es, um es auf Live-Seiten anzuzeigen.',
|
|
1139
|
+
// EC-728 — Rückgängig von „Wiederverwendbar machen“: der Block ist zurück, das erstellte Dokument bleibt.
|
|
1140
|
+
'builder.reuse.undoKeptPublished': 'Rückgängig gemacht — das wiederverwendbare Element „{name}“ bleibt: Es ist veröffentlicht.',
|
|
1141
|
+
'builder.reuse.undoKeptEdited': 'Rückgängig gemacht — das wiederverwendbare Element „{name}“ bleibt: Es wurde seit dem Erstellen bearbeitet.',
|
|
1142
|
+
'builder.reuse.undoKeptReferenced': 'Rückgängig gemacht — das wiederverwendbare Element „{name}“ bleibt: Es ist an anderer Stelle eingebettet.',
|
|
1143
|
+
'builder.reuse.undoKeptFailed': 'Rückgängig gemacht — das wiederverwendbare Element „{name}“ bleibt: Es konnte nicht entfernt werden. Löschen Sie es in seiner Sammlung, wenn Sie es nicht brauchen.',
|
|
1132
1144
|
'builder.reuse.noTargetToDetach': 'Dieses Element hat kein Ziel zum Loslösen.',
|
|
1133
1145
|
'builder.reuse.noContentToDetach': 'Das referenzierte Element hat keinen Inhalt zum Loslösen.',
|
|
1134
1146
|
'builder.reuse.detachedToCopy': 'Als bearbeitbare Kopie losgelöst — die Live-Verknüpfung ist getrennt.',
|
|
@@ -1339,6 +1351,10 @@ export const deMessages = {
|
|
|
1339
1351
|
'ai.update.proposalTitle': 'Änderungen an {collection}',
|
|
1340
1352
|
'ai.update.diffBefore': 'Aktuell',
|
|
1341
1353
|
'ai.update.diffAfter': 'Vorgeschlagen',
|
|
1354
|
+
'ai.create.unfilledTitle': 'Leer gelassen ({count})',
|
|
1355
|
+
'ai.create.unfilled.empty': 'der Entwurf hat keinen Wert gesetzt',
|
|
1356
|
+
'ai.create.unfilled.noCandidates': 'nichts, wonach der Assistent gesucht hat, passt dazu',
|
|
1357
|
+
'ai.create.unfilled.dropped': 'eine ID, nach der der Assistent nicht gesucht hatte, wurde entfernt',
|
|
1342
1358
|
// EC-591 — Hinweise auf der Arbeitsfläche für Rollen, die keine Komponente der Liste füllt.
|
|
1343
1359
|
'builder.roles.noStack': 'Diese Arbeitsfläche braucht eine Komponente mit der Rolle "layout.stack" — die Blöcke des Feldes werden darin angeordnet —, und die Komponenten dieses Projekts haben keine. Tragen Sie eine in die Komponentenliste Ihrer Konfiguration ein (zum Beispiel Stack aus @elytracms/components).',
|
|
1344
1360
|
'builder.roles.noGrid': 'Keine Komponente füllt die Rolle "layout.grid" — Blöcke nebeneinander ablegen (Spalten) ist deshalb aus.',
|