@elytracms/studio 0.0.95 → 0.0.96
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/cms.ts +124 -8
- package/convex/strict-reference-race.test.ts +139 -0
- package/dist/components/ai/ai-chat-panel.js +15 -2
- package/dist/components/ai/ai-chat-panel.js.map +1 -1
- package/dist/components/ai/translate-document-action.d.ts +6 -0
- package/dist/components/ai/translate-document-action.js.map +1 -1
- package/dist/components/ai/translate-document-dialog.d.ts +1 -1
- package/dist/components/ai/translate-document-dialog.js +5 -5
- package/dist/components/ai/translate-document-dialog.js.map +1 -1
- package/dist/components/assets/asset-detail.js +5 -2
- package/dist/components/assets/asset-detail.js.map +1 -1
- package/dist/components/assets/asset-locale.d.ts +7 -0
- package/dist/components/assets/asset-locale.js +16 -2
- package/dist/components/assets/asset-locale.js.map +1 -1
- package/dist/components/assets/asset-meta-drift-notice.d.ts +13 -0
- package/dist/components/assets/asset-meta-drift-notice.js +22 -0
- package/dist/components/assets/asset-meta-drift-notice.js.map +1 -0
- package/dist/components/assets/asset-meta-label.d.ts +2 -1
- package/dist/components/assets/asset-meta-label.js +4 -2
- package/dist/components/assets/asset-meta-label.js.map +1 -1
- package/dist/components/assets/asset-metadata.d.ts +33 -13
- package/dist/components/assets/asset-metadata.js +46 -22
- package/dist/components/assets/asset-metadata.js.map +1 -1
- package/dist/components/assets/asset-search.d.ts +6 -2
- package/dist/components/assets/asset-search.js +15 -5
- package/dist/components/assets/asset-search.js.map +1 -1
- package/dist/components/assets/assets-collection-view-source.d.ts +5 -3
- package/dist/components/assets/assets-collection-view-source.js +7 -5
- package/dist/components/assets/assets-collection-view-source.js.map +1 -1
- package/dist/components/builder/canvas-rebase.d.ts +36 -12
- package/dist/components/builder/canvas-rebase.js +13 -3
- package/dist/components/builder/canvas-rebase.js.map +1 -1
- package/dist/components/builder/canvas-render-context.js +5 -4
- package/dist/components/builder/canvas-render-context.js.map +1 -1
- package/dist/components/builder/composition-field-editor.d.ts +12 -6
- package/dist/components/builder/composition-field-editor.js +6 -5
- package/dist/components/builder/composition-field-editor.js.map +1 -1
- package/dist/components/cms/asset-picker-core.d.ts +2 -2
- package/dist/components/cms/asset-picker-core.js +2 -2
- package/dist/components/cms/asset-picker-core.js.map +1 -1
- package/dist/components/cms/asset-picker.js +3 -1
- package/dist/components/cms/asset-picker.js.map +1 -1
- package/dist/components/cms/canvas-commit.d.ts +6 -0
- package/dist/components/cms/canvas-commit.js +5 -1
- package/dist/components/cms/canvas-commit.js.map +1 -1
- package/dist/components/cms/cms-store.d.ts +21 -8
- package/dist/components/cms/cms-store.js +19 -10
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/collection-table.js +4 -11
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/detail-editor.js +2 -2
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/draft-commit.d.ts +16 -3
- package/dist/components/cms/draft-commit.js +3 -2
- package/dist/components/cms/draft-commit.js.map +1 -1
- package/dist/components/cms/use-document-draft.d.ts +67 -9
- package/dist/components/cms/use-document-draft.js +112 -39
- package/dist/components/cms/use-document-draft.js.map +1 -1
- package/dist/components/collection-view/cms-collection-view-source.js +6 -4
- package/dist/components/collection-view/cms-collection-view-source.js.map +1 -1
- package/dist/components/components/transfer-dialog.js +6 -4
- package/dist/components/components/transfer-dialog.js.map +1 -1
- package/dist/lib/ai/chat-state.d.ts +7 -0
- package/dist/lib/ai/chat-state.js.map +1 -1
- package/dist/lib/ai/tools.d.ts +8 -0
- package/dist/lib/ai/tools.js +4 -0
- package/dist/lib/ai/tools.js.map +1 -1
- package/dist/lib/cms-views/view-model.d.ts +15 -8
- package/dist/lib/cms-views/view-model.js +19 -5
- package/dist/lib/cms-views/view-model.js.map +1 -1
- package/dist/lib/collection-view/__fixtures__/document-writes.js +1 -0
- package/dist/lib/collection-view/__fixtures__/document-writes.js.map +1 -1
- package/dist/lib/collection-view/collection-view-source.d.ts +15 -7
- package/dist/lib/collection-view/collection-view-source.js.map +1 -1
- package/dist/lib/data/collection-content.js +5 -0
- package/dist/lib/data/collection-content.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.js +13 -1
- package/dist/lib/i18n/messages.de.js.map +1 -1
- package/dist/lib/i18n/messages.en.d.ts +11 -0
- package/dist/lib/i18n/messages.en.js +14 -1
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/operations/cms-persistence.d.ts +80 -35
- package/dist/lib/operations/cms-persistence.js +348 -85
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.js +54 -8
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/dist/lib/persona/labels.js +1 -0
- package/dist/lib/persona/labels.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-model.js","sourceRoot":"","sources":["../../../src/lib/cms-views/view-model.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod'\nimport {\n canonicalDateValue,\n configViewSchema,\n filterClauseSchema,\n filterScalarSchema,\n isPseudoColumn,\n PUBLISHED_AT_FIELD,\n resolveField,\n resolveLabel,\n STATE_FIELD,\n titleFieldOf,\n UPDATED_AT_FIELD,\n URL_FIELD,\n viewSortSchema,\n} from '@elytracms/core/cms-core'\nimport { localizedLabel, translate } from '../i18n'\nimport { contentQueryErrorMessage } from '../persona/labels'\nimport type {\n CmsDocument,\n CollectionDef,\n ConfigView,\n FieldDef,\n FilterClause,\n Locale,\n LocaleConfig,\n LocalizedString,\n ViewSort,\n} from '@elytracms/core/cms-core'\nimport {\n compareListEntries,\n sortScalarOf,\n filterableFields,\n matchesFieldValue,\n validateWhere,\n} from '@elytracms/core/content'\nimport type {\n FilterCondition,\n FilterOperator,\n FilterScalar,\n NormalizedCondition,\n WhereInput,\n} from '@elytracms/core/content'\n\n/**\n * The pure table-view model for the CMS collection table (EC-169).\n *\n * A view bundles three things: filters in the closed AD-3 vocabulary\n * (`eq`/`in`/`lt`/`lte`/`gt`/`gte`, AND-only — exactly `@elytracms/core/content`'s\n * query model, evaluated with the same matching/ordering primitives), a sort\n * (field + direction), and the visible/ordered columns. Everything here is\n * plain data + functions so filtering, dirtiness, and column edits are\n * testable without a DOM.\n *\n * Filters are offered ONLY on fields the schema declares `filterable: true`\n * (EC-143), plus one built-in option: the document's publication state. The\n * state is document metadata, not a schema field — it powers the\n * \"show me drafts → bulk publish\" working set and still speaks only the\n * closed vocabulary (`eq`/`in`).\n */\n\n// --- Schemas (single source of truth — persisted view records reuse these) ----\n\n// EC-622: the authoring shape of a view and the reserved `$` keys are declared ONCE, in\n// cms-core (`collection-views.ts`), where the config gate judges every declared view —\n// re-exported here unchanged, so this module's public names stay what they were.\nexport {\n configViewSchema,\n filterClauseSchema,\n filterScalarSchema,\n isPseudoColumn,\n PUBLISHED_AT_FIELD,\n STATE_FIELD,\n UPDATED_AT_FIELD,\n URL_FIELD,\n viewSortSchema,\n}\nexport type { ConfigView, FilterClause, ViewSort }\n\nexport const tableViewStateSchema = z.object({\n /** AND-only list of conditions (no OR, no nesting — vision AD-3). */\n filters: z.array(filterClauseSchema),\n sort: viewSortSchema.nullable(),\n /**\n * The canonical column order (field names) — EVERY column, visible or not\n * (EC-213). Order is independent of visibility: hiding then re-showing a\n * column keeps its place. Schema fields absent here resolve in at the end\n * (see {@link resolveColumns}).\n */\n columns: z.array(z.string().min(1)),\n /**\n * The subset of {@link TableViewState.columns} that is hidden. Defaults to\n * `[]` so views persisted before EC-213 (no `hidden` key) load unchanged.\n */\n hidden: z.array(z.string().min(1)).default([]),\n})\nexport type TableViewState = z.infer<typeof tableViewStateSchema>\n\n// --- The built-in publication-state filter column ------------------------------\n\n// `STATE_FIELD` (the publication-state sentinel) and the reserved pseudo-COLUMN keys\n// (`$url`, `$updatedAt`, `$publishedAt` — EC-445/EC-447) are declared in cms-core\n// (`collection-views.ts`, EC-622) and re-exported above. `$state` is a reserved key\n// (filter + sort) but NOT a reorderable column: EC-448 made it the FIXED structural\n// leading column, so {@link pseudoColumns} never emits it and an authored view listing\n// `$state` is a harmless no-op (see {@link resolveConfigColumns}). Which reserved key\n// APPLIES to a collection is this module's runtime decision ({@link pseudoColumns}); the\n// config gate accepts every reserved key.\n\nconst STATE_VALUES = ['draft', 'published'] as const\n\n// --- Reserved pseudo-COLUMNS (EC-445) ------------------------------------------\n\n/**\n * Pseudo-columns HIDDEN by default (opt-in): the extra publish timestamp. Everything\n * else applicable (`$updatedAt`/`$state`/`$url`) is on by default (owner, 2026-07-17).\n */\nconst DEFAULT_HIDDEN_PSEUDO_COLUMNS: ReadonlySet<string> = new Set([PUBLISHED_AT_FIELD])\n\n/**\n * Capability signals that make a pseudo-column applicable to a collection/source\n * (EC-445). Supplied by the caller from the portable source — the model stays pure.\n */\nexport interface PseudoColumnOptions {\n /** The source materializes per-document timestamps → `$updatedAt` applies. */\n timestamps?: boolean\n /**\n * The collection has a publish lifecycle. Gates `$publishedAt` (with `timestamps`).\n * EC-448: it no longer gates a reorderable `$state` column — `$state` is the FIXED\n * structural status column, gated by the same signal at the render site, not here.\n */\n publishing?: boolean\n /** The collection resolves delivery URLs → `$url` applies (mirrors `urlByDocId`). */\n routable?: boolean\n}\n\n/**\n * The reserved REORDERABLE pseudo-columns that APPLY to a collection, in their default\n * appended order (EC-445/EC-447): `$updatedAt`, `$publishedAt`, then `$url`. `$url` is\n * gated on `routable` (a non-routable collection has no URL column, not an empty one),\n * `$updatedAt` on `timestamps`. `$publishedAt` (EC-447) needs BOTH `timestamps` (its\n * materialized value) AND `publishing` (a publish lifecycle to have a publish date) —\n * it is OPT-IN, HIDDEN by default (`DEFAULT_HIDDEN_PSEUDO_COLUMNS`), so it joins the\n * universe/picker without appearing in the baseline lens.\n *\n * NOTE (EC-448): `$state` is NO LONGER emitted here. It became a FIXED structural\n * leading column (checkbox → status-dot → title), rendered by `collection-table.tsx`\n * regardless of the reorderable model — so it is never in the order/hide/picker set,\n * even though `publishing` is what gates BOTH it and the status column's presence.\n * `opts.publishing` therefore only affects `$publishedAt` here. Pure — a caller\n * (`pseudoColumnsForSource`) supplies the signals from the source.\n */\nexport function pseudoColumns(collection: CollectionDef, opts: PseudoColumnOptions = {}): string[] {\n void collection // reserved for future per-collection gating; kept for API symmetry\n const cols: string[] = []\n if (opts.timestamps) cols.push(UPDATED_AT_FIELD)\n // EC-447: a publish date needs both a timestamps source (the value) AND a publish\n // lifecycle (the meaning). Hidden by default → surfaced via the Display picker / a\n // config view's `columns`, never a blank column on a rail that can't publish.\n if (opts.timestamps && opts.publishing) cols.push(PUBLISHED_AT_FIELD)\n // EC-448: $state is structural (fixed leading column), not a reorderable pseudo-column.\n if (opts.routable) cols.push(URL_FIELD)\n return cols\n}\n\n/**\n * The per-document metadata accessors the pseudo-DATE columns sort by (EC-445) — the\n * columns-axis analogue of {@link IsPublished}. Threaded into the sort machinery so a\n * `$updatedAt`/`$publishedAt` sort orders by the source's materialized timestamp; a\n * missing accessor (fixtures/tests) sorts those rows last. `$url` is derived → never sorted.\n */\nexport interface PseudoColumnMeta {\n updatedAt?(doc: CmsDocument): string | undefined\n publishedAt?(doc: CmsDocument): string | undefined\n}\n\n/** One field the filter builder may offer. */\nexport interface FilterableFieldOption {\n /** Clause field key: a schema field name, or {@link STATE_FIELD}. */\n field: string\n label: string\n /** The schema field def, or `null` for the built-in publication state. */\n def: FieldDef | null\n}\n\nexport const STATE_OPTION: FilterableFieldOption = {\n field: STATE_FIELD,\n label: 'State',\n def: null,\n}\n\n/**\n * The closed list of fields the filter builder offers: exactly the schema's\n * `filterable: true` fields (EC-143) plus the publication state. Nothing else\n * is ever offered — the UI builds queries, it does not invent a language.\n */\nexport function filterableFieldOptions(collection: CollectionDef): FilterableFieldOption[] {\n const schemaOptions = filterableFields(collection).map((field) => ({\n field: field.name,\n label: localizedLabel(field.form?.label, field.name),\n def: field,\n }))\n return [...schemaOptions, STATE_OPTION]\n}\n\nexport function filterOptionFor(\n collection: CollectionDef,\n field: string,\n): FilterableFieldOption | undefined {\n return filterableFieldOptions(collection).find((option) => option.field === field)\n}\n\n// --- Operators per field type (EC-345) ------------------------------------------\n\n/**\n * The per-type operator SET the builder offers (EC-345), always a subset of the\n * closed `FILTER_OPERATORS` — the UI narrows the vocabulary, it never extends it.\n * Ratified sets (Oli, 2026-07-08):\n *\n * - text: contains (default) · equals · starts with · ends with · empty\n * - number: equals · < · ≤ · > · ≥ · empty\n * - date: equals · before · … · after · empty (same ops as number, date labels)\n * - boolean: is\n * - select: is · is any of · empty\n * - relation / asset: is · is any of · empty (relation value = the relation picker;\n * `eq` on a `multiple` relation is membership — array-contains, EC-255 semantics)\n * - state pseudo-field: is · is any of (unchanged — a publication state is never empty)\n */\nexport function operatorsFor(option: FilterableFieldOption): FilterOperator[] {\n if (option.def === null) return ['eq', 'in'] // publication state\n switch (option.def.type) {\n case 'boolean':\n return ['eq']\n case 'number':\n case 'date':\n return ['eq', 'lt', 'lte', 'gt', 'gte', 'empty']\n case 'select':\n case 'relation':\n case 'asset':\n return ['eq', 'in', 'empty']\n default:\n // text (and any other string-shaped field)\n return ['contains', 'eq', 'startsWith', 'endsWith', 'empty']\n }\n}\n\n/**\n * A visual choice in the operator dropdown (EC-345). Usually one per operator,\n * but `empty` splits into two — \"is empty\" (`true`) and \"is not empty\" (`false`) —\n * so an editor never has to reason about a boolean value; the choice carries the\n * preset. `token` is the `<option value>`, `labelKey` a catalog key ({@link operatorLabelKey}).\n */\nexport interface OperatorChoice {\n token: string\n op: FilterOperator\n /** Value forced when this choice is picked (the `empty` true/false), else undefined. */\n presetValue?: FilterScalar\n labelKey: string\n}\n\n/**\n * The operator dropdown entries for a field (EC-345): {@link operatorsFor} expanded\n * for display, with `empty` shown as the two self-describing choices.\n */\nexport function operatorChoices(option: FilterableFieldOption): OperatorChoice[] {\n const choices: OperatorChoice[] = []\n for (const op of operatorsFor(option)) {\n if (op === 'empty') {\n choices.push({ token: 'empty:true', op, presetValue: true, labelKey: 'cms.filter.op.isEmpty' })\n choices.push({\n token: 'empty:false',\n op,\n presetValue: false,\n labelKey: 'cms.filter.op.isNotEmpty',\n })\n continue\n }\n choices.push({ token: op, op, labelKey: operatorLabelKey(op, option) })\n }\n return choices\n}\n\n/**\n * The catalog key for an operator's label (EC-241/EC-345), keyed by operator AND\n * field type — `eq` reads \"equals\" on text/number, \"on\" on a date, \"is\" on an\n * enum-like field; `lt` reads \"less than\" on a number, \"before\" on a date. `empty`\n * additionally depends on its VALUE (is empty / is not empty). Pure → unit-tested.\n */\nexport function operatorLabelKey(\n op: FilterOperator,\n option: FilterableFieldOption | undefined,\n value?: FilterScalar | readonly FilterScalar[],\n): string {\n const type = option?.def?.type\n switch (op) {\n case 'contains':\n return 'cms.filter.op.contains'\n case 'startsWith':\n return 'cms.filter.op.startsWith'\n case 'endsWith':\n return 'cms.filter.op.endsWith'\n case 'in':\n return 'cms.filter.op.isAnyOf'\n case 'empty':\n return value === false ? 'cms.filter.op.isNotEmpty' : 'cms.filter.op.isEmpty'\n case 'eq':\n // \"on\" for a date; \"is\" for enum-like refs; \"equals\" for text/number/unknown\n // (and the publication-state pseudo-field, whose `def` is null → unchanged).\n if (type === 'date') return 'cms.filter.op.on'\n if (type === 'boolean' || type === 'select' || type === 'relation' || type === 'asset') {\n return 'cms.filter.op.is'\n }\n return 'cms.filter.op.equals'\n case 'lt':\n return type === 'date' ? 'cms.filter.op.before' : 'cms.filter.op.lessThan'\n case 'lte':\n return type === 'date' ? 'cms.filter.op.onOrBefore' : 'cms.filter.op.atMost'\n case 'gt':\n return type === 'date' ? 'cms.filter.op.after' : 'cms.filter.op.greaterThan'\n case 'gte':\n return type === 'date' ? 'cms.filter.op.onOrAfter' : 'cms.filter.op.atLeast'\n }\n}\n\n/** A sensible starting clause when a field is added to the builder (EC-345). */\nexport function defaultClause(option: FilterableFieldOption): FilterClause {\n if (option.def === null) return { field: STATE_FIELD, op: 'eq', value: 'published' }\n switch (option.def.type) {\n case 'boolean':\n return { field: option.field, op: 'eq', value: true }\n case 'number':\n case 'date':\n return { field: option.field, op: 'eq', value: option.def.type === 'number' ? 0 : '' }\n case 'select':\n return { field: option.field, op: 'eq', value: option.def.options[0]?.value ?? '' }\n case 'relation':\n case 'asset':\n return { field: option.field, op: 'eq', value: '' }\n default:\n // text (and any other string-shaped field): `contains` is the natural default\n return { field: option.field, op: 'contains', value: '' }\n }\n}\n\n// --- Text ⇄ scalar coercion (the value inputs of the builder) -------------------\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/\n\n/** Coerce one text input into the scalar a clause compares against. */\nexport function scalarFromText(\n option: FilterableFieldOption | undefined,\n raw: string,\n): FilterScalar {\n const type = option?.def?.type\n if (type === 'number') {\n const trimmed = raw.trim()\n if (trimmed === '') return raw // an emptied input must not become eq 0\n const parsed = Number(trimmed)\n return Number.isNaN(parsed) ? raw : parsed\n }\n if (type === 'boolean') return raw === 'true'\n // EC-586: a date operand goes through THE date canonicaliser — the same one every\n // write and the comparator use — so `2026-09-18` means midnight UTC on that day.\n if (type === 'date' && DATE_ONLY.test(raw)) return canonicalDateValue(raw) ?? raw\n return raw\n}\n\n/** Parse a comma-separated list for the `in` operator. */\nexport function scalarListFromText(\n option: FilterableFieldOption | undefined,\n raw: string,\n): FilterScalar[] {\n return raw\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part !== '')\n .map((part) => scalarFromText(option, part))\n}\n\nexport function scalarListToText(value: FilterScalar | FilterScalar[]): string {\n const list = Array.isArray(value) ? value : [value]\n return list.map(String).join(', ')\n}\n\n// --- Clause validation -----------------------------------------------------------\n\n/** A structured problem with one clause (by index in the filter list). */\nexport interface ClauseIssue {\n index: number\n message: string\n}\n\n/**\n * Validate clauses against the collection schema. Schema-field clauses run\n * through the canonical `validateWhere` (EC-143: `filterable` enforcement +\n * operator/value shape); state clauses check the `eq`/`in` subset and the\n * draft/published value set. Invalid clauses (e.g. a persisted view whose\n * field is no longer filterable) are reported — never silently applied.\n *\n * EC-494 — the two `$state` sentences are authored HERE, studio-side, so they call\n * `translate` directly; the schema-field ones come from `core/content`, below the\n * catalog in the DAG, and are resolved from the `messageRef` that error now carries.\n * Both halves of one line therefore render in the same language.\n */\nexport function validateClauses(\n collection: CollectionDef,\n clauses: readonly FilterClause[],\n): ClauseIssue[] {\n const issues: ClauseIssue[] = []\n clauses.forEach((clause, index) => {\n if (clause.field === STATE_FIELD) {\n if (clause.op !== 'eq' && clause.op !== 'in') {\n issues.push({ index, message: translate('cms.filter.issue.stateOperator') })\n return\n }\n const values = Array.isArray(clause.value) ? clause.value : [clause.value]\n if (!values.every((value) => (STATE_VALUES as readonly unknown[]).includes(value))) {\n issues.push({ index, message: translate('cms.filter.issue.stateValue') })\n }\n return\n }\n const where: WhereInput = {\n [clause.field]: { [clause.op]: clause.value } as FilterCondition,\n }\n const errors = validateWhere(collection, where)\n if (errors.length > 0) issues.push({ index, message: contentQueryErrorMessage(errors[0]!) })\n })\n return issues\n}\n\n// --- Matching & sorting (delegates to @elytracms/core/content's primitives) -------------\n\n/**\n * Published-ness source for the `$state` pseudo-field (EC-224): the version\n * POINTER, supplied by the caller as `cms.isPublished`. Defaults to \"nothing\n * published\" — a bare row carries no publish signal now that the flat `state`\n * field is gone, so the table (which knows the pointer) passes the real\n * predicate; fixtures/tests that don't surface `$state` get the safe default.\n */\nexport type IsPublished = (doc: CmsDocument) => boolean\nconst defaultIsPublished: IsPublished = () => false\n\n/**\n * The RAW locale-resolved value a document exposes for a clause field — an array\n * for a `multiple` relation/asset, a ref object for a single one, a scalar\n * otherwise. Matching runs on this (via `matchesFieldValue`) so it agrees with the\n * delivery/listing path exactly: array-contains for `multiple` relations (EC-255)\n * and whole-value `empty` semantics (EC-345). Sorting keeps its own scalar reduction.\n *\n * EC-580: read in the DISPLAYED view of the table's active locale (`resolveField`,\n * the per-field form of `valuesInLocale`) — what the row shows is what it sorts and\n * filters by, as delivery does in the request locale. It used to read a\n * per-document default locale, so a `de` table sorted by English values.\n */\nfunction rawValueOf(\n collection: CollectionDef,\n doc: CmsDocument,\n field: string,\n localeConfig: LocaleConfig,\n locale: Locale,\n isPublished: IsPublished,\n): unknown {\n if (field === STATE_FIELD) return isPublished(doc) ? 'published' : 'draft'\n if (!collection.fields.some((f) => f.name === field)) return undefined\n return resolveField(collection, doc, field, locale, localeConfig).value\n}\n\n/** The scalar a document exposes for a SORT field, in the active locale's view. */\nfunction scalarOf(\n collection: CollectionDef,\n doc: CmsDocument,\n field: string,\n localeConfig: LocaleConfig,\n locale: Locale,\n isPublished: IsPublished,\n meta: PseudoColumnMeta = {},\n): FilterScalar | null {\n if (field === STATE_FIELD) return isPublished(doc) ? 'published' : 'draft'\n // EC-445: the pseudo-DATE columns sort by the source's materialized ISO timestamp\n // (ISO strings order lexicographically = chronologically); `$url` is derived → not sortable.\n if (field === UPDATED_AT_FIELD) return meta.updatedAt?.(doc) ?? null\n if (field === PUBLISHED_AT_FIELD) return meta.publishedAt?.(doc) ?? null\n if (field === URL_FIELD) return null\n const def = collection.fields.find((f) => f.name === field)\n if (!def) return null\n // EC-586: a `date` sorts as the instant it denotes (`sortScalarOf`), as delivery does.\n return sortScalarOf(resolveField(collection, doc, field, locale, localeConfig).value, def)\n}\n\n/**\n * Does a document satisfy one clause? Identical verdict to the content accessors'\n * delivery/listing path: both reduce to `@elytracms/core/content`'s\n * `matchesFieldValue` over the RAW field value (so `contains`/`empty`/multiple-\n * relation membership all behave the same on the table as on the live site).\n */\nexport function clauseMatches(\n collection: CollectionDef,\n doc: CmsDocument,\n localeConfig: LocaleConfig,\n locale: Locale,\n clause: FilterClause,\n isPublished: IsPublished = defaultIsPublished,\n): boolean {\n const value = rawValueOf(collection, doc, clause.field, localeConfig, locale, isPublished)\n const condition = { [clause.op]: clause.value } as NormalizedCondition\n // EC-586: the field def makes a `date` compare as an instant — delivery's exact rule.\n return matchesFieldValue(value, condition, collection.fields.find((f) => f.name === clause.field))\n}\n\n/**\n * Sort documents by one column in the canonical deterministic order\n * (`compareListEntries`: typed value order, id-ascending tiebreak). Unlike the\n * content accessors, the *table* may sort any rendered column — sorting is a\n * presentation concern here; the `filterable` flag governs filters.\n */\nexport function sortViewDocuments(\n collection: CollectionDef,\n docs: readonly CmsDocument[],\n localeConfig: LocaleConfig,\n locale: Locale,\n sort: ViewSort | null,\n isPublished: IsPublished = defaultIsPublished,\n meta: PseudoColumnMeta = {},\n): CmsDocument[] {\n if (sort === null) return [...docs]\n const positions = new Map(\n docs.map((doc) => [\n doc.id,\n scalarOf(collection, doc, sort.field, localeConfig, locale, isPublished, meta),\n ]),\n )\n return [...docs].sort((a, b) =>\n compareListEntries(\n { id: a.id, sortValue: positions.get(a.id) ?? null },\n { id: b.id, sortValue: positions.get(b.id) ?? null },\n sort.dir,\n ),\n )\n}\n\n/** The filtered + sorted documents of a view, plus any clause issues. */\nexport interface AppliedViewState {\n docs: CmsDocument[]\n /** Clauses that failed validation — reported AND excluded from matching. */\n issues: ClauseIssue[]\n}\n\n/**\n * Apply a view state to a document list: validate clauses, AND-match the valid\n * ones, sort. Invalid clauses never filter silently — they come back as\n * issues for the UI to surface.\n */\nexport function applyViewState(\n collection: CollectionDef,\n docs: readonly CmsDocument[],\n localeConfig: LocaleConfig,\n locale: Locale,\n state: TableViewState,\n isPublished: IsPublished = defaultIsPublished,\n meta: PseudoColumnMeta = {},\n): AppliedViewState {\n const issues = validateClauses(collection, state.filters)\n const invalid = new Set(issues.map((issue) => issue.index))\n const active = state.filters.filter((_, index) => !invalid.has(index))\n const matched = docs.filter((doc) =>\n active.every((clause) =>\n clauseMatches(collection, doc, localeConfig, locale, clause, isPublished),\n ),\n )\n return {\n docs: sortViewDocuments(collection, matched, localeConfig, locale, state.sort, isPublished, meta),\n issues,\n }\n}\n\n// --- View state construction, equality, columns ----------------------------------\n\n/** The id of the synthesized built-in \"All entries\" baseline view (EC-444). */\nexport const ALL_VIEW_ID = 'all'\n\n/** The default (unnamed) view: no filters, no sort, every field visible. */\n/**\n * Field types kept OFF the default table columns (EC-246b): the composite editing\n * surfaces — a blocks canvas, rich text, a structured object/repeater — read as\n * noise in a scalar list. `filterable` no longer forces (or governs) a column; the\n * default lens is \"all scalars\". These stay in the column picker one toggle away,\n * and any named view may list them in its `columns`; they're just off by default.\n */\nconst NON_DEFAULT_COLUMN_TYPES = new Set<FieldDef['type']>(['blocks', 'richText', 'object'])\n\n/**\n * Field names OFF the built-in baseline lens by default: exactly the composite\n * editing surfaces (blocks/richText/object) — always noise in a scalar list. The\n * default lens is \"all scalars\"; there is no per-field column opt-out any more\n * (EC-444 hard-removed `form.column`). A field stays in the picker one toggle away,\n * and a view curates columns by declaring an explicit `columns` list (or the\n * `id: 'default'` baseline override).\n */\nfunction defaultHiddenColumns(collection: CollectionDef, pseudo: readonly string[] = []): string[] {\n const composites = collection.fields\n .filter((f) => NON_DEFAULT_COLUMN_TYPES.has(f.type))\n .map((f) => f.name)\n // EC-445: applicable opt-in pseudo-columns ($publishedAt) start hidden; the rest\n // ($updatedAt/$state/$url) are visible by default (owner: keep them on).\n const hiddenPseudo = pseudo.filter((name) => DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(name))\n return [...composites, ...hiddenPseudo]\n}\n\nexport function defaultViewState(\n collection: CollectionDef,\n pseudo: readonly string[] = [],\n): TableViewState {\n return {\n filters: [],\n sort: null,\n // Every field keeps a slot (order + picker), but the composite surfaces start\n // hidden so the default lens is the collection's scalar columns (EC-246b/EC-444).\n // EC-445: the applicable reserved pseudo-columns append after the data columns.\n columns: orderedColumnNames(collection, pseudo),\n hidden: defaultHiddenColumns(collection, pseudo),\n }\n}\n\n/**\n * Resolve an authored VISIBLE column list (EC-444) into the internal two-axis\n * `{columns, hidden}` table state. The authored list is exactly the columns shown,\n * in order; every OTHER schema field is appended (in schema order) and hidden — the\n * same shape {@link defaultViewState} produces, so {@link resolveColumns} renders\n * precisely the authored list, visible, in that order. An omitted (or empty) list\n * inherits the collection's default lens (all scalars visible, composites hidden).\n * An authored name outside the universe — no longer a field, or a reserved column that\n * does not apply to this source — is skipped here so the list still renders; a name that\n * is neither a top-level field nor a reserved `$` key never reaches a resolved config\n * (EC-622: the config gate refuses it, `collectionViewFindings`).\n */\nexport function resolveConfigColumns(\n collection: CollectionDef,\n visible: readonly string[] | undefined,\n pseudo: readonly string[] = [],\n): Pick<TableViewState, 'columns' | 'hidden'> {\n if (visible === undefined || visible.length === 0) {\n const base = defaultViewState(collection, pseudo)\n return { columns: base.columns, hidden: base.hidden }\n }\n const universe = orderedColumnNames(collection, pseudo)\n const inUniverse = new Set(universe)\n const seen = new Set<string>()\n const shown: string[] = []\n for (const name of visible) {\n if (inUniverse.has(name) && !seen.has(name)) {\n shown.push(name)\n seen.add(name)\n }\n }\n const rest = universe.filter((name) => !seen.has(name))\n // EC-445: a schema-ONLY authored list (mentioning no pseudo-column) keeps the\n // applicable pseudo-columns at their DEFAULT visibility — so a consumer's\n // pre-EC-445 `columns:[…schema…]` list still shows today's url (+ updatedAt).\n // Mentioning ANY reorderable pseudo-column switches them to the visible-list rule\n // (only listed shows). EC-448: `$state` is EXCLUDED here — it is a fixed structural\n // column, not a reorderable one, so an authored `$state` is an inert no-op: it must\n // not flip the visible-list rule (nor is it in the universe, so it is simply dropped).\n const mentionsPseudo = visible.some((name) => isPseudoColumn(name) && name !== STATE_FIELD)\n const keepVisible = mentionsPseudo\n ? new Set<string>()\n : new Set(pseudo.filter((name) => !DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(name)))\n const hidden = rest.filter((name) => !keepVisible.has(name))\n return { columns: [...shown, ...rest], hidden }\n}\n\n/** The reserved `views[]` id whose entry OVERRIDES the synthesized baseline view (EC-444). */\nexport const DEFAULT_VIEW_OVERRIDE_ID = 'default'\n\n// A config-declared view's authoring shape (`configViewSchema` / `ConfigView`, EC-246b/\n// EC-444) is cms-core's (EC-622) — imported and re-exported at the top of this module.\n\n/**\n * A resolved view: identity + the table state it restores (matches `SavedView`).\n * `name` stays a {@link LocalizedString} — resolved at the render site (EC-343), like\n * `form.label`. `initial` marks the first-load seed (see {@link defaultConfigViewId}),\n * resolved from the authored `initial ?? default` flag (EC-444).\n */\nexport interface ResolvedView {\n id: string\n name: LocalizedString\n state: TableViewState\n initial?: boolean\n}\n\n/**\n * Slug used to derive a config view's stable id from its name. A localized name\n * (EC-343) slugs its DEFAULT-locale text so the id is stable across the active UI\n * locale (an id must not shift when a German editor loads the same config).\n */\nfunction configViewId(name: LocalizedString, index: number): string {\n const text = resolveLabel(name) ?? ''\n const slug = text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return `config:${slug || index}`\n}\n\n/**\n * Resolve a collection's config-declared `views` into full {@link ResolvedView}s\n * (EC-246b). Each is validated with {@link configViewSchema}; malformed entries\n * and duplicate ids are skipped (defensive — a malformed view never reaches a resolved\n * config: the config gate refuses it, EC-622). Columns fall back to the collection\n * default when a view doesn't pin them, so a filter-only view still renders every\n * column. Config views are shared and change only in\n * code — the runtime never mutates them.\n */\nexport function configViewsFor(\n collection: CollectionDef,\n pseudo: readonly string[] = [],\n): ResolvedView[] {\n const declared = collection.views\n if (!Array.isArray(declared)) return []\n const seen = new Set<string>()\n const resolved: ResolvedView[] = []\n declared.forEach((raw, index) => {\n const parsed = configViewSchema.safeParse(raw)\n if (!parsed.success) return\n const view = parsed.data\n const id = view.id ?? configViewId(view.name, index)\n if (seen.has(id)) return\n seen.add(id)\n // EC-444: `initial` supersedes the deprecated `default` alias (one-release window).\n const initial = view.initial ?? view.default\n const { columns, hidden } = resolveConfigColumns(collection, view.columns, pseudo)\n resolved.push({\n id,\n name: view.name,\n ...(initial ? { initial: true } : {}),\n state: normalizeViewState({\n filters: view.filters ?? [],\n sort: view.sort ?? null,\n columns,\n hidden,\n }),\n })\n })\n return resolved\n}\n\n/**\n * Does the collection declare a baseline-override view (a config view whose id is\n * {@link DEFAULT_VIEW_OVERRIDE_ID})? When true the synthesized \"All entries\" lens is\n * replaced by that entry verbatim (see {@link resolveCollectionViews}), EC-444.\n */\nexport function hasDefaultViewOverride(collection: CollectionDef): boolean {\n return configViewsFor(collection).some((view) => view.id === DEFAULT_VIEW_OVERRIDE_ID)\n}\n\n/**\n * The ordered view list a collection surfaces (EC-444): the baseline first, then the\n * config-declared views in declaration order. The baseline is either an authored\n * OVERRIDE (the config view whose id is {@link DEFAULT_VIEW_OVERRIDE_ID}, used\n * VERBATIM and NOT repeated among the trailing views) or, absent one, the\n * `synthesizedBaseline` the caller passes (the studio's translated \"All entries\"\n * lens). Pure — the store supplies the synthesized baseline (i18n-bound `name`).\n */\nexport function resolveCollectionViews(\n collection: CollectionDef,\n synthesizedBaseline: ResolvedView,\n pseudo: readonly string[] = [],\n): ResolvedView[] {\n const configViews = configViewsFor(collection, pseudo)\n const overrideIndex = configViews.findIndex((view) => view.id === DEFAULT_VIEW_OVERRIDE_ID)\n if (overrideIndex < 0) return [synthesizedBaseline, ...configViews]\n const override = configViews[overrideIndex]!\n const rest = configViews.filter((_, index) => index !== overrideIndex)\n return [override, ...rest]\n}\n\n/**\n * The ids of config views that still use the DEPRECATED `default` flag without the\n * new `initial` (EC-444). Drives the one-release deprecation warning (mirrors the\n * duplicate-default channel); empty once every view has migrated to `initial`.\n */\nexport function deprecatedDefaultFlagViewIds(collection: CollectionDef): string[] {\n const declared = collection.views\n if (!Array.isArray(declared)) return []\n const seen = new Set<string>()\n const ids: string[] = []\n declared.forEach((raw, index) => {\n const parsed = configViewSchema.safeParse(raw)\n if (!parsed.success) return\n const view = parsed.data\n const id = view.id ?? configViewId(view.name, index)\n if (seen.has(id)) return\n seen.add(id)\n if (view.default !== undefined && view.initial === undefined) ids.push(id)\n })\n return ids\n}\n\n/**\n * The id of the config view flagged `initial: true` (EC-343/EC-444; `default` read\n * as a deprecated alias) — the seed for a collection's INITIAL active view. When\n * several are flagged (a misconfiguration, reported by {@link configViewIssues}) the\n * FIRST in declaration order wins deterministically; when none is flagged the caller\n * falls back to the baseline lens. `undefined` when the collection flags none.\n */\nexport function defaultConfigViewId(collection: CollectionDef): string | undefined {\n return configViewsFor(collection).find((view) => view.initial)?.id\n}\n\n/** A config-level problem with a collection's declared views (EC-343/EC-444). */\nexport interface ConfigViewIssue {\n /** Stable code (kept from EC-343 to avoid catalog churn); reads \"duplicate initial\". */\n code: 'duplicate-default'\n message: string\n /** The offending view ids (all views flagged `initial`, in declaration order). */\n viewIds: string[]\n}\n\n/**\n * Validate a collection's config-declared views (EC-343/EC-444): at most one may set\n * `initial: true` (`default` counted as its deprecated alias). A duplicate is returned\n * as an explicit, structured issue — never silently swallowed — so the studio can\n * surface it (the first still wins deterministically for seeding, per\n * {@link defaultConfigViewId}). Pure and schema-only; the DOM-free counterpart of the\n * \"failures are first-class\" contract.\n */\nexport function configViewIssues(collection: CollectionDef): ConfigViewIssue[] {\n const initials = configViewsFor(collection).filter((view) => view.initial)\n if (initials.length <= 1) return []\n const viewIds = initials.map((view) => view.id)\n return [\n {\n code: 'duplicate-default',\n message: `Collection \"${collection.id}\" declares ${initials.length} initial views (${viewIds.join(', ')}); at most one view may set \\`initial: true\\`. Seeding \"${viewIds[0]}\".`,\n viewIds,\n },\n ]\n}\n\n/**\n * The default column order: the schema's title field first (it becomes the\n * default title/link column — EC-213 drops the separate primary-column\n * selector, treating the first visible column as the title), then the\n * remaining fields in schema order.\n */\nfunction orderedColumnNames(collection: CollectionDef, pseudo: readonly string[] = []): string[] {\n const names = collection.fields.map((field) => field.name)\n const title = titleFieldOf(collection)?.name\n const schemaOrdered =\n title === undefined || !names.includes(title)\n ? names\n : [title, ...names.filter((name) => name !== title)]\n // EC-445: the column UNIVERSE = schema fields, then the applicable reserved\n // pseudo-columns (they are NOT in `collection.fields`).\n return [...schemaOrdered, ...pseudo]\n}\n\n/** Deep-cloned canonical form (stable key order via the Zod shape). */\nexport function normalizeViewState(state: TableViewState): TableViewState {\n return tableViewStateSchema.parse(state)\n}\n\n/** Structural equality on normalized states — drives the \"unsaved changes\" affordance. */\nexport function viewStatesEqual(a: TableViewState, b: TableViewState): boolean {\n return JSON.stringify(normalizeViewState(a)) === JSON.stringify(normalizeViewState(b))\n}\n\n/** One column of a view resolved against the current schema (EC-213). */\nexport interface ResolvedColumn {\n /** The schema field name. */\n field: string\n /** Whether the column renders (`false` ⇒ in {@link TableViewState.hidden}). */\n visible: boolean\n}\n\n/**\n * Resolve a view's columns against the live schema (EC-213): every schema\n * field exactly once, in the view's saved order, with any fields the view\n * predates appended (visible) and any fields no longer in the schema dropped.\n * This is the single source of truth for \"which columns, in what order, shown\n * or hidden\" — order is preserved across hide/show because visibility lives in\n * `hidden`, never in the order.\n */\nexport function resolveColumns(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): ResolvedColumn[] {\n const schemaNames = collection.fields.map((field) => field.name)\n // EC-445: the valid universe to KEEP from the saved order is schema fields PLUS the\n // applicable pseudo-columns (which are not in `collection.fields`) — so a seeded\n // `$state`/`$url`/`$updatedAt` is preserved + ordered, never dropped as \"unknown\".\n const keep = new Set([...schemaNames, ...pseudo])\n const hidden = new Set(state.hidden)\n const inState = new Set(state.columns)\n // Keep the saved order, restricted to the live universe and de-duplicated (a\n // corrupted persisted state must never render one field as two columns).\n const ordered: string[] = []\n const seen = new Set<string>()\n for (const name of state.columns) {\n if (keep.has(name) && !seen.has(name)) {\n ordered.push(name)\n seen.add(name)\n }\n }\n // Append universe members the saved order predates: new schema fields (EC-213\n // discovery), then applicable pseudo-columns not yet placed (EC-445).\n const appended = [\n ...schemaNames.filter((name) => !seen.has(name)),\n ...pseudo.filter((name) => !seen.has(name)),\n ]\n return [...ordered, ...appended].map((field) => {\n // A freshly-appended opt-in pseudo-column ($publishedAt) starts hidden; once it\n // is in the saved order (an editor un-hid it) its visibility follows `hidden`.\n const defaultHiddenAppend = DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(field) && !inState.has(field)\n return { field, visible: !hidden.has(field) && !defaultHiddenAppend }\n })\n}\n\n/** The visible columns of a view, in render order (EC-213). */\nexport function visibleColumns(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): string[] {\n return resolveColumns(collection, state, pseudo)\n .filter((column) => column.visible)\n .map((column) => column.field)\n}\n\n/**\n * The title/link column — the document IDENTITY column (EC-242): the schema title\n * field, shown as the leftmost linked cell whose content is `resolveDocumentTitle`\n * (a string `titleField` or a function pattern). Always present regardless of\n * column visibility — it is the document's identity, not a toggleable data column —\n * and excluded from the data columns so the title never shows twice. Falls back to\n * the first visible column, then the first field, then `id`, when no title field\n * is resolvable (e.g. a function title with no backing `title` field).\n */\nexport function primaryColumn(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): string {\n return (\n titleFieldOf(collection)?.name ??\n // EC-445: a pseudo-column is never the identity column (it has no title value) —\n // fall back to the first visible SCHEMA column.\n visibleColumns(collection, state, pseudo).find((name) => !isPseudoColumn(name)) ??\n collection.fields[0]?.name ??\n 'id'\n )\n}\n\n/**\n * Reconcile `columns` to the full resolved order so column edits operate on a\n * complete, stable order (drops removed fields, pins appended ones), and prune\n * `hidden` to fields the live schema still has (a column removed from the schema\n * must not leave dead `hidden` cruft that trips dirty-detection / persists).\n */\nfunction withResolvedOrder(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): TableViewState {\n const columns = resolveColumns(collection, state, pseudo).map((column) => column.field)\n const live = new Set(columns)\n const hidden = state.hidden.filter((name) => live.has(name))\n return { ...state, columns, hidden }\n}\n\n/**\n * The canonical, schema-resolved form of a view state — full column order with\n * `hidden` pruned to live fields (EC-213). Two states that render identically\n * share one canonical form, so dirty-detection never trips on a mere column\n * reconciliation or a stale `hidden` entry (only a real filter/sort/visibility/\n * order change counts as \"unsaved\").\n */\nexport function canonicalViewState(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): TableViewState {\n return normalizeViewState(withResolvedOrder(collection, state, pseudo))\n}\n\n/**\n * Toggle a column's visibility — position is preserved (EC-213): visibility\n * lives in `hidden`, the order in `columns` is untouched. Columns the saved\n * order predates are pinned into `columns` first so their place is stable.\n */\nexport function toggleColumn(\n collection: CollectionDef,\n state: TableViewState,\n field: string,\n pseudo: readonly string[] = [],\n): TableViewState {\n const base = withResolvedOrder(collection, state, pseudo)\n const hidden = base.hidden.includes(field)\n ? base.hidden.filter((name) => name !== field)\n : [...base.hidden, field]\n return { ...base, hidden }\n}\n\n/** Move a column one position left (-1) or right (+1) in the full column order. */\nexport function moveColumn(\n collection: CollectionDef,\n state: TableViewState,\n field: string,\n delta: -1 | 1,\n pseudo: readonly string[] = [],\n): TableViewState {\n const base = withResolvedOrder(collection, state, pseudo)\n const from = base.columns.indexOf(field)\n const to = from + delta\n if (from < 0 || to < 0 || to >= base.columns.length) return state\n const columns = [...base.columns]\n columns.splice(from, 1)\n columns.splice(to, 0, field)\n return { ...base, columns }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"view-model.js","sourceRoot":"","sources":["../../../src/lib/cms-views/view-model.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod'\nimport {\n canonicalDateValue,\n configViewSchema,\n filterClauseSchema,\n filterScalarSchema,\n isPseudoColumn,\n PUBLISHED_AT_FIELD,\n resolveField,\n resolveLabel,\n STATE_FIELD,\n titleFieldOf,\n UPDATED_AT_FIELD,\n URL_FIELD,\n sortSchema,\n} from '@elytracms/core/cms-core'\nimport { localizedLabel, translate } from '../i18n'\nimport { contentQueryErrorMessage } from '../persona/labels'\nimport type {\n CmsDocument,\n CollectionDef,\n ConfigView,\n FieldDef,\n FilterClause,\n Locale,\n LocaleConfig,\n LocalizedString,\n Sort,\n} from '@elytracms/core/cms-core'\nimport {\n compareListEntries,\n sortScalarOf,\n filterableFields,\n matchesFieldValue,\n validateWhere,\n} from '@elytracms/core/content'\nimport type {\n FilterCondition,\n FilterOperator,\n FilterScalar,\n NormalizedCondition,\n WhereInput,\n} from '@elytracms/core/content'\n\n/**\n * The pure table-view model for the CMS collection table (EC-169).\n *\n * A view bundles three things: filters in the closed AD-3 vocabulary\n * (`eq`/`in`/`lt`/`lte`/`gt`/`gte`, AND-only — exactly `@elytracms/core/content`'s\n * query model, evaluated with the same matching/ordering primitives), a sort\n * (field + direction), and the visible/ordered columns. Everything here is\n * plain data + functions so filtering, dirtiness, and column edits are\n * testable without a DOM.\n *\n * Filters are offered ONLY on fields the schema declares `filterable: true`\n * (EC-143), plus one built-in option: the document's publication state. The\n * state is document metadata, not a schema field — it powers the\n * \"show me drafts → bulk publish\" working set and still speaks only the\n * closed vocabulary (`eq`/`in`).\n */\n\n// --- Schemas (single source of truth — persisted view records reuse these) ----\n\n// EC-622: the authoring shape of a view and the reserved `$` keys are declared ONCE, in\n// cms-core (`collection-views.ts`), where the config gate judges every declared view —\n// re-exported here unchanged, so this module's public names stay what they were. EC-660:\n// a view's sort is THE sort shape (cms-core `list-query.ts`: `{ field, direction }`, a\n// listing's and `listDocuments`' too), re-exported as `sortSchema` / `Sort` — the views'\n// own `dir`-spelled schema is gone.\nexport {\n configViewSchema,\n filterClauseSchema,\n filterScalarSchema,\n isPseudoColumn,\n PUBLISHED_AT_FIELD,\n sortSchema,\n STATE_FIELD,\n UPDATED_AT_FIELD,\n URL_FIELD,\n}\nexport type { ConfigView, FilterClause, Sort }\n\nexport const tableViewStateSchema = z.object({\n /** AND-only list of conditions (no OR, no nesting — vision AD-3). */\n filters: z.array(filterClauseSchema),\n sort: sortSchema.nullable(),\n /**\n * The canonical column order (field names) — EVERY column, visible or not\n * (EC-213). Order is independent of visibility: hiding then re-showing a\n * column keeps its place. Schema fields absent here resolve in at the end\n * (see {@link resolveColumns}).\n */\n columns: z.array(z.string().min(1)),\n /**\n * The subset of {@link TableViewState.columns} that is hidden. Defaults to\n * `[]` so views persisted before EC-213 (no `hidden` key) load unchanged.\n */\n hidden: z.array(z.string().min(1)).default([]),\n})\nexport type TableViewState = z.infer<typeof tableViewStateSchema>\n\n// --- The built-in publication-state filter column ------------------------------\n\n// `STATE_FIELD` (the publication-state sentinel) and the reserved pseudo-COLUMN keys\n// (`$url`, `$updatedAt`, `$publishedAt` — EC-445/EC-447) are declared in cms-core\n// (`collection-views.ts`, EC-622) and re-exported above. `$state` is a reserved key\n// (filter + sort) but NOT a reorderable column: EC-448 made it the FIXED structural\n// leading column, so {@link pseudoColumns} never emits it and an authored view listing\n// `$state` is a harmless no-op (see {@link resolveConfigColumns}). Which reserved key\n// APPLIES to a collection is this module's runtime decision ({@link pseudoColumns}); the\n// config gate accepts every reserved key.\n\nconst STATE_VALUES = ['draft', 'published'] as const\n\n// --- Reserved pseudo-COLUMNS (EC-445) ------------------------------------------\n\n/**\n * Pseudo-columns HIDDEN by default (opt-in): the extra publish timestamp. Everything\n * else applicable (`$updatedAt`/`$state`/`$url`) is on by default (owner, 2026-07-17).\n */\nconst DEFAULT_HIDDEN_PSEUDO_COLUMNS: ReadonlySet<string> = new Set([PUBLISHED_AT_FIELD])\n\n/**\n * Capability signals that make a pseudo-column applicable to a collection/source\n * (EC-445). Supplied by the caller from the portable source — the model stays pure.\n */\nexport interface PseudoColumnOptions {\n /** The source materializes per-document timestamps → `$updatedAt` applies. */\n timestamps?: boolean\n /**\n * The collection has a publish lifecycle. Gates `$publishedAt` (with `timestamps`).\n * EC-448: it no longer gates a reorderable `$state` column — `$state` is the FIXED\n * structural status column, gated by the same signal at the render site, not here.\n */\n publishing?: boolean\n /** The collection resolves delivery URLs → `$url` applies (mirrors `urlByDocId`). */\n routable?: boolean\n}\n\n/**\n * The reserved REORDERABLE pseudo-columns that APPLY to a collection, in their default\n * appended order (EC-445/EC-447): `$updatedAt`, `$publishedAt`, then `$url`. `$url` is\n * gated on `routable` (a non-routable collection has no URL column, not an empty one),\n * `$updatedAt` on `timestamps`. `$publishedAt` (EC-447) needs BOTH `timestamps` (its\n * materialized value) AND `publishing` (a publish lifecycle to have a publish date) —\n * it is OPT-IN, HIDDEN by default (`DEFAULT_HIDDEN_PSEUDO_COLUMNS`), so it joins the\n * universe/picker without appearing in the baseline lens.\n *\n * NOTE (EC-448): `$state` is NO LONGER emitted here. It became a FIXED structural\n * leading column (checkbox → status-dot → title), rendered by `collection-table.tsx`\n * regardless of the reorderable model — so it is never in the order/hide/picker set,\n * even though `publishing` is what gates BOTH it and the status column's presence.\n * `opts.publishing` therefore only affects `$publishedAt` here. Pure — a caller\n * (`pseudoColumnsForSource`) supplies the signals from the source.\n */\nexport function pseudoColumns(collection: CollectionDef, opts: PseudoColumnOptions = {}): string[] {\n void collection // reserved for future per-collection gating; kept for API symmetry\n const cols: string[] = []\n if (opts.timestamps) cols.push(UPDATED_AT_FIELD)\n // EC-447: a publish date needs both a timestamps source (the value) AND a publish\n // lifecycle (the meaning). Hidden by default → surfaced via the Display picker / a\n // config view's `columns`, never a blank column on a rail that can't publish.\n if (opts.timestamps && opts.publishing) cols.push(PUBLISHED_AT_FIELD)\n // EC-448: $state is structural (fixed leading column), not a reorderable pseudo-column.\n if (opts.routable) cols.push(URL_FIELD)\n return cols\n}\n\n/**\n * The per-document metadata accessors the pseudo-DATE columns sort by (EC-445) — the\n * columns-axis analogue of {@link IsPublished}. Threaded into the sort machinery so a\n * `$updatedAt`/`$publishedAt` sort orders by the source's materialized timestamp; a\n * missing accessor (fixtures/tests) sorts those rows last. `$url` is derived → never sorted.\n */\nexport interface PseudoColumnMeta {\n updatedAt?(doc: CmsDocument): string | undefined\n publishedAt?(doc: CmsDocument): string | undefined\n}\n\n/** One field the filter builder may offer. */\nexport interface FilterableFieldOption {\n /** Clause field key: a schema field name, or {@link STATE_FIELD}. */\n field: string\n label: string\n /** The schema field def, or `null` for the built-in publication state. */\n def: FieldDef | null\n}\n\nexport const STATE_OPTION: FilterableFieldOption = {\n field: STATE_FIELD,\n label: 'State',\n def: null,\n}\n\n/**\n * The closed list of fields the filter builder offers: exactly the schema's\n * `filterable: true` fields (EC-143) plus the publication state. Nothing else\n * is ever offered — the UI builds queries, it does not invent a language.\n */\nexport function filterableFieldOptions(collection: CollectionDef): FilterableFieldOption[] {\n const schemaOptions = filterableFields(collection).map((field) => ({\n field: field.name,\n label: localizedLabel(field.form?.label, field.name),\n def: field,\n }))\n return [...schemaOptions, STATE_OPTION]\n}\n\nexport function filterOptionFor(\n collection: CollectionDef,\n field: string,\n): FilterableFieldOption | undefined {\n return filterableFieldOptions(collection).find((option) => option.field === field)\n}\n\n// --- Operators per field type (EC-345) ------------------------------------------\n\n/**\n * The per-type operator SET the builder offers (EC-345), always a subset of the\n * closed `FILTER_OPERATORS` — the UI narrows the vocabulary, it never extends it.\n * Ratified sets (Oli, 2026-07-08):\n *\n * - text: contains (default) · equals · starts with · ends with · empty\n * - number: equals · < · ≤ · > · ≥ · empty\n * - date: equals · before · … · after · empty (same ops as number, date labels)\n * - boolean: is\n * - select: is · is any of · empty\n * - relation / asset: is · is any of · empty (relation value = the relation picker;\n * `eq` on a `multiple` relation is membership — array-contains, EC-255 semantics)\n * - state pseudo-field: is · is any of (unchanged — a publication state is never empty)\n */\nexport function operatorsFor(option: FilterableFieldOption): FilterOperator[] {\n if (option.def === null) return ['eq', 'in'] // publication state\n switch (option.def.type) {\n case 'boolean':\n return ['eq']\n case 'number':\n case 'date':\n return ['eq', 'lt', 'lte', 'gt', 'gte', 'empty']\n case 'select':\n case 'relation':\n case 'asset':\n return ['eq', 'in', 'empty']\n default:\n // text (and any other string-shaped field)\n return ['contains', 'eq', 'startsWith', 'endsWith', 'empty']\n }\n}\n\n/**\n * A visual choice in the operator dropdown (EC-345). Usually one per operator,\n * but `empty` splits into two — \"is empty\" (`true`) and \"is not empty\" (`false`) —\n * so an editor never has to reason about a boolean value; the choice carries the\n * preset. `token` is the `<option value>`, `labelKey` a catalog key ({@link operatorLabelKey}).\n */\nexport interface OperatorChoice {\n token: string\n op: FilterOperator\n /** Value forced when this choice is picked (the `empty` true/false), else undefined. */\n presetValue?: FilterScalar\n labelKey: string\n}\n\n/**\n * The operator dropdown entries for a field (EC-345): {@link operatorsFor} expanded\n * for display, with `empty` shown as the two self-describing choices.\n */\nexport function operatorChoices(option: FilterableFieldOption): OperatorChoice[] {\n const choices: OperatorChoice[] = []\n for (const op of operatorsFor(option)) {\n if (op === 'empty') {\n choices.push({ token: 'empty:true', op, presetValue: true, labelKey: 'cms.filter.op.isEmpty' })\n choices.push({\n token: 'empty:false',\n op,\n presetValue: false,\n labelKey: 'cms.filter.op.isNotEmpty',\n })\n continue\n }\n choices.push({ token: op, op, labelKey: operatorLabelKey(op, option) })\n }\n return choices\n}\n\n/**\n * The catalog key for an operator's label (EC-241/EC-345), keyed by operator AND\n * field type — `eq` reads \"equals\" on text/number, \"on\" on a date, \"is\" on an\n * enum-like field; `lt` reads \"less than\" on a number, \"before\" on a date. `empty`\n * additionally depends on its VALUE (is empty / is not empty). Pure → unit-tested.\n */\nexport function operatorLabelKey(\n op: FilterOperator,\n option: FilterableFieldOption | undefined,\n value?: FilterScalar | readonly FilterScalar[],\n): string {\n const type = option?.def?.type\n switch (op) {\n case 'contains':\n return 'cms.filter.op.contains'\n case 'startsWith':\n return 'cms.filter.op.startsWith'\n case 'endsWith':\n return 'cms.filter.op.endsWith'\n case 'in':\n return 'cms.filter.op.isAnyOf'\n case 'empty':\n return value === false ? 'cms.filter.op.isNotEmpty' : 'cms.filter.op.isEmpty'\n case 'eq':\n // \"on\" for a date; \"is\" for enum-like refs; \"equals\" for text/number/unknown\n // (and the publication-state pseudo-field, whose `def` is null → unchanged).\n if (type === 'date') return 'cms.filter.op.on'\n if (type === 'boolean' || type === 'select' || type === 'relation' || type === 'asset') {\n return 'cms.filter.op.is'\n }\n return 'cms.filter.op.equals'\n case 'lt':\n return type === 'date' ? 'cms.filter.op.before' : 'cms.filter.op.lessThan'\n case 'lte':\n return type === 'date' ? 'cms.filter.op.onOrBefore' : 'cms.filter.op.atMost'\n case 'gt':\n return type === 'date' ? 'cms.filter.op.after' : 'cms.filter.op.greaterThan'\n case 'gte':\n return type === 'date' ? 'cms.filter.op.onOrAfter' : 'cms.filter.op.atLeast'\n }\n}\n\n/** A sensible starting clause when a field is added to the builder (EC-345). */\nexport function defaultClause(option: FilterableFieldOption): FilterClause {\n if (option.def === null) return { field: STATE_FIELD, op: 'eq', value: 'published' }\n switch (option.def.type) {\n case 'boolean':\n return { field: option.field, op: 'eq', value: true }\n case 'number':\n case 'date':\n return { field: option.field, op: 'eq', value: option.def.type === 'number' ? 0 : '' }\n case 'select':\n return { field: option.field, op: 'eq', value: option.def.options[0]?.value ?? '' }\n case 'relation':\n case 'asset':\n return { field: option.field, op: 'eq', value: '' }\n default:\n // text (and any other string-shaped field): `contains` is the natural default\n return { field: option.field, op: 'contains', value: '' }\n }\n}\n\n// --- Text ⇄ scalar coercion (the value inputs of the builder) -------------------\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/\n\n/** Coerce one text input into the scalar a clause compares against. */\nexport function scalarFromText(\n option: FilterableFieldOption | undefined,\n raw: string,\n): FilterScalar {\n const type = option?.def?.type\n if (type === 'number') {\n const trimmed = raw.trim()\n if (trimmed === '') return raw // an emptied input must not become eq 0\n const parsed = Number(trimmed)\n return Number.isNaN(parsed) ? raw : parsed\n }\n if (type === 'boolean') return raw === 'true'\n // EC-586: a date operand goes through THE date canonicaliser — the same one every\n // write and the comparator use — so `2026-09-18` means midnight UTC on that day.\n if (type === 'date' && DATE_ONLY.test(raw)) return canonicalDateValue(raw) ?? raw\n return raw\n}\n\n/** Parse a comma-separated list for the `in` operator. */\nexport function scalarListFromText(\n option: FilterableFieldOption | undefined,\n raw: string,\n): FilterScalar[] {\n return raw\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part !== '')\n .map((part) => scalarFromText(option, part))\n}\n\nexport function scalarListToText(value: FilterScalar | FilterScalar[]): string {\n const list = Array.isArray(value) ? value : [value]\n return list.map(String).join(', ')\n}\n\n// --- Clause validation -----------------------------------------------------------\n\n/** A structured problem with one clause (by index in the filter list). */\nexport interface ClauseIssue {\n index: number\n message: string\n}\n\n/**\n * Validate clauses against the collection schema. Schema-field clauses run\n * through the canonical `validateWhere` (EC-143: `filterable` enforcement +\n * operator/value shape); state clauses check the `eq`/`in` subset and the\n * draft/published value set. Invalid clauses (e.g. a persisted view whose\n * field is no longer filterable) are reported — never silently applied.\n *\n * EC-494 — the two `$state` sentences are authored HERE, studio-side, so they call\n * `translate` directly; the schema-field ones come from `core/content`, below the\n * catalog in the DAG, and are resolved from the `messageRef` that error now carries.\n * Both halves of one line therefore render in the same language.\n */\nexport function validateClauses(\n collection: CollectionDef,\n clauses: readonly FilterClause[],\n): ClauseIssue[] {\n const issues: ClauseIssue[] = []\n clauses.forEach((clause, index) => {\n if (clause.field === STATE_FIELD) {\n if (clause.op !== 'eq' && clause.op !== 'in') {\n issues.push({ index, message: translate('cms.filter.issue.stateOperator') })\n return\n }\n const values = Array.isArray(clause.value) ? clause.value : [clause.value]\n if (!values.every((value) => (STATE_VALUES as readonly unknown[]).includes(value))) {\n issues.push({ index, message: translate('cms.filter.issue.stateValue') })\n }\n return\n }\n const where: WhereInput = {\n [clause.field]: { [clause.op]: clause.value } as FilterCondition,\n }\n const errors = validateWhere(collection, where)\n if (errors.length > 0) issues.push({ index, message: contentQueryErrorMessage(errors[0]!) })\n })\n return issues\n}\n\n// --- Matching & sorting (delegates to @elytracms/core/content's primitives) -------------\n\n/**\n * Published-ness source for the `$state` pseudo-field (EC-224): the version\n * POINTER, supplied by the caller as `cms.isPublished`. Defaults to \"nothing\n * published\" — a bare row carries no publish signal now that the flat `state`\n * field is gone, so the table (which knows the pointer) passes the real\n * predicate; fixtures/tests that don't surface `$state` get the safe default.\n */\nexport type IsPublished = (doc: CmsDocument) => boolean\nconst defaultIsPublished: IsPublished = () => false\n\n/**\n * The RAW locale-resolved value a document exposes for a clause field — an array\n * for a `multiple` relation/asset, a ref object for a single one, a scalar\n * otherwise. Matching runs on this (via `matchesFieldValue`) so it agrees with the\n * delivery/listing path exactly: array-contains for `multiple` relations (EC-255)\n * and whole-value `empty` semantics (EC-345). Sorting keeps its own scalar reduction.\n *\n * EC-580: read in the DISPLAYED view of the table's active locale (`resolveField`,\n * the per-field form of `valuesInLocale`) — what the row shows is what it sorts and\n * filters by, as delivery does in the request locale. It used to read a\n * per-document default locale, so a `de` table sorted by English values.\n */\nfunction rawValueOf(\n collection: CollectionDef,\n doc: CmsDocument,\n field: string,\n localeConfig: LocaleConfig,\n locale: Locale,\n isPublished: IsPublished,\n): unknown {\n if (field === STATE_FIELD) return isPublished(doc) ? 'published' : 'draft'\n if (!collection.fields.some((f) => f.name === field)) return undefined\n return resolveField(collection, doc, field, locale, localeConfig).value\n}\n\n/** The scalar a document exposes for a SORT field, in the active locale's view. */\nfunction scalarOf(\n collection: CollectionDef,\n doc: CmsDocument,\n field: string,\n localeConfig: LocaleConfig,\n locale: Locale,\n isPublished: IsPublished,\n meta: PseudoColumnMeta = {},\n): FilterScalar | null {\n if (field === STATE_FIELD) return isPublished(doc) ? 'published' : 'draft'\n // EC-445: the pseudo-DATE columns sort by the source's materialized ISO timestamp\n // (ISO strings order lexicographically = chronologically); `$url` is derived → not sortable.\n if (field === UPDATED_AT_FIELD) return meta.updatedAt?.(doc) ?? null\n if (field === PUBLISHED_AT_FIELD) return meta.publishedAt?.(doc) ?? null\n if (field === URL_FIELD) return null\n const def = collection.fields.find((f) => f.name === field)\n if (!def) return null\n // EC-586: a `date` sorts as the instant it denotes (`sortScalarOf`), as delivery does.\n return sortScalarOf(resolveField(collection, doc, field, locale, localeConfig).value, def)\n}\n\n/**\n * Does a document satisfy one clause? Identical verdict to the content accessors'\n * delivery/listing path: both reduce to `@elytracms/core/content`'s\n * `matchesFieldValue` over the RAW field value (so `contains`/`empty`/multiple-\n * relation membership all behave the same on the table as on the live site).\n */\nexport function clauseMatches(\n collection: CollectionDef,\n doc: CmsDocument,\n localeConfig: LocaleConfig,\n locale: Locale,\n clause: FilterClause,\n isPublished: IsPublished = defaultIsPublished,\n): boolean {\n const value = rawValueOf(collection, doc, clause.field, localeConfig, locale, isPublished)\n const condition = { [clause.op]: clause.value } as NormalizedCondition\n // EC-586: the field def makes a `date` compare as an instant — delivery's exact rule.\n return matchesFieldValue(value, condition, collection.fields.find((f) => f.name === clause.field))\n}\n\n/**\n * The sort a column header click leads to (EC-169): a new column sorts ascending, the\n * active one flips to descending, then clears. Reads `direction`, which every parsed\n * sort carries — THE sort shape normalises an omitted one to `'asc'` (EC-660), so a\n * config view declared `{ field }` flips on its first click instead of clearing.\n */\nexport function nextHeaderSort(prev: Sort | null, field: string): Sort | null {\n if (prev?.field !== field) return { field, direction: 'asc' }\n return prev.direction === 'asc' ? { field, direction: 'desc' } : null\n}\n\n/**\n * Sort documents by one column in the canonical deterministic order\n * (`compareListEntries`: typed value order, id-ascending tiebreak). Unlike the\n * content accessors, the *table* may sort any rendered column — sorting is a\n * presentation concern here; the `filterable` flag governs filters.\n */\nexport function sortViewDocuments(\n collection: CollectionDef,\n docs: readonly CmsDocument[],\n localeConfig: LocaleConfig,\n locale: Locale,\n sort: Sort | null,\n isPublished: IsPublished = defaultIsPublished,\n meta: PseudoColumnMeta = {},\n): CmsDocument[] {\n if (sort === null) return [...docs]\n const positions = new Map(\n docs.map((doc) => [\n doc.id,\n scalarOf(collection, doc, sort.field, localeConfig, locale, isPublished, meta),\n ]),\n )\n return [...docs].sort((a, b) =>\n compareListEntries(\n { id: a.id, sortValue: positions.get(a.id) ?? null },\n { id: b.id, sortValue: positions.get(b.id) ?? null },\n sort.direction,\n ),\n )\n}\n\n/** The filtered + sorted documents of a view, plus any clause issues. */\nexport interface AppliedViewState {\n docs: CmsDocument[]\n /** Clauses that failed validation — reported AND excluded from matching. */\n issues: ClauseIssue[]\n}\n\n/**\n * Apply a view state to a document list: validate clauses, AND-match the valid\n * ones, sort. Invalid clauses never filter silently — they come back as\n * issues for the UI to surface.\n */\nexport function applyViewState(\n collection: CollectionDef,\n docs: readonly CmsDocument[],\n localeConfig: LocaleConfig,\n locale: Locale,\n state: TableViewState,\n isPublished: IsPublished = defaultIsPublished,\n meta: PseudoColumnMeta = {},\n): AppliedViewState {\n const issues = validateClauses(collection, state.filters)\n const invalid = new Set(issues.map((issue) => issue.index))\n const active = state.filters.filter((_, index) => !invalid.has(index))\n const matched = docs.filter((doc) =>\n active.every((clause) =>\n clauseMatches(collection, doc, localeConfig, locale, clause, isPublished),\n ),\n )\n return {\n docs: sortViewDocuments(collection, matched, localeConfig, locale, state.sort, isPublished, meta),\n issues,\n }\n}\n\n// --- View state construction, equality, columns ----------------------------------\n\n/** The id of the synthesized built-in \"All entries\" baseline view (EC-444). */\nexport const ALL_VIEW_ID = 'all'\n\n/** The default (unnamed) view: no filters, no sort, every field visible. */\n/**\n * Field types kept OFF the default table columns (EC-246b): the composite editing\n * surfaces — a blocks canvas, rich text, a structured object/repeater — read as\n * noise in a scalar list. `filterable` no longer forces (or governs) a column; the\n * default lens is \"all scalars\". These stay in the column picker one toggle away,\n * and any named view may list them in its `columns`; they're just off by default.\n */\nconst NON_DEFAULT_COLUMN_TYPES = new Set<FieldDef['type']>(['blocks', 'richText', 'object'])\n\n/**\n * Field names OFF the built-in baseline lens by default: exactly the composite\n * editing surfaces (blocks/richText/object) — always noise in a scalar list. The\n * default lens is \"all scalars\"; there is no per-field column opt-out any more\n * (EC-444 hard-removed `form.column`). A field stays in the picker one toggle away,\n * and a view curates columns by declaring an explicit `columns` list (or the\n * `id: 'default'` baseline override).\n */\nfunction defaultHiddenColumns(collection: CollectionDef, pseudo: readonly string[] = []): string[] {\n const composites = collection.fields\n .filter((f) => NON_DEFAULT_COLUMN_TYPES.has(f.type))\n .map((f) => f.name)\n // EC-445: applicable opt-in pseudo-columns ($publishedAt) start hidden; the rest\n // ($updatedAt/$state/$url) are visible by default (owner: keep them on).\n const hiddenPseudo = pseudo.filter((name) => DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(name))\n return [...composites, ...hiddenPseudo]\n}\n\nexport function defaultViewState(\n collection: CollectionDef,\n pseudo: readonly string[] = [],\n): TableViewState {\n return {\n filters: [],\n sort: null,\n // Every field keeps a slot (order + picker), but the composite surfaces start\n // hidden so the default lens is the collection's scalar columns (EC-246b/EC-444).\n // EC-445: the applicable reserved pseudo-columns append after the data columns.\n columns: orderedColumnNames(collection, pseudo),\n hidden: defaultHiddenColumns(collection, pseudo),\n }\n}\n\n/**\n * Resolve an authored VISIBLE column list (EC-444) into the internal two-axis\n * `{columns, hidden}` table state. The authored list is exactly the columns shown,\n * in order; every OTHER schema field is appended (in schema order) and hidden — the\n * same shape {@link defaultViewState} produces, so {@link resolveColumns} renders\n * precisely the authored list, visible, in that order. An omitted (or empty) list\n * inherits the collection's default lens (all scalars visible, composites hidden).\n * An authored name outside the universe — no longer a field, or a reserved column that\n * does not apply to this source — is skipped here so the list still renders; a name that\n * is neither a top-level field nor a reserved `$` key never reaches a resolved config\n * (EC-622: the config gate refuses it, `collectionViewFindings`).\n */\nexport function resolveConfigColumns(\n collection: CollectionDef,\n visible: readonly string[] | undefined,\n pseudo: readonly string[] = [],\n): Pick<TableViewState, 'columns' | 'hidden'> {\n if (visible === undefined || visible.length === 0) {\n const base = defaultViewState(collection, pseudo)\n return { columns: base.columns, hidden: base.hidden }\n }\n const universe = orderedColumnNames(collection, pseudo)\n const inUniverse = new Set(universe)\n const seen = new Set<string>()\n const shown: string[] = []\n for (const name of visible) {\n if (inUniverse.has(name) && !seen.has(name)) {\n shown.push(name)\n seen.add(name)\n }\n }\n const rest = universe.filter((name) => !seen.has(name))\n // EC-445: a schema-ONLY authored list (mentioning no pseudo-column) keeps the\n // applicable pseudo-columns at their DEFAULT visibility — so a consumer's\n // pre-EC-445 `columns:[…schema…]` list still shows today's url (+ updatedAt).\n // Mentioning ANY reorderable pseudo-column switches them to the visible-list rule\n // (only listed shows). EC-448: `$state` is EXCLUDED here — it is a fixed structural\n // column, not a reorderable one, so an authored `$state` is an inert no-op: it must\n // not flip the visible-list rule (nor is it in the universe, so it is simply dropped).\n const mentionsPseudo = visible.some((name) => isPseudoColumn(name) && name !== STATE_FIELD)\n const keepVisible = mentionsPseudo\n ? new Set<string>()\n : new Set(pseudo.filter((name) => !DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(name)))\n const hidden = rest.filter((name) => !keepVisible.has(name))\n return { columns: [...shown, ...rest], hidden }\n}\n\n/** The reserved `views[]` id whose entry OVERRIDES the synthesized baseline view (EC-444). */\nexport const DEFAULT_VIEW_OVERRIDE_ID = 'default'\n\n// A config-declared view's authoring shape (`configViewSchema` / `ConfigView`, EC-246b/\n// EC-444) is cms-core's (EC-622) — imported and re-exported at the top of this module.\n\n/**\n * A resolved view: identity + the table state it restores (matches `SavedView`).\n * `name` stays a {@link LocalizedString} — resolved at the render site (EC-343), like\n * `form.label`. `initial` marks the first-load seed (see {@link defaultConfigViewId}),\n * resolved from the authored `initial ?? default` flag (EC-444).\n */\nexport interface ResolvedView {\n id: string\n name: LocalizedString\n state: TableViewState\n initial?: boolean\n}\n\n/**\n * Slug used to derive a config view's stable id from its name. A localized name\n * (EC-343) slugs its DEFAULT-locale text so the id is stable across the active UI\n * locale (an id must not shift when a German editor loads the same config).\n */\nfunction configViewId(name: LocalizedString, index: number): string {\n const text = resolveLabel(name) ?? ''\n const slug = text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return `config:${slug || index}`\n}\n\n/**\n * Resolve a collection's config-declared `views` into full {@link ResolvedView}s\n * (EC-246b). Each is validated with {@link configViewSchema}; malformed entries\n * and duplicate ids are skipped (defensive — a malformed view never reaches a resolved\n * config: the config gate refuses it, EC-622). Columns fall back to the collection\n * default when a view doesn't pin them, so a filter-only view still renders every\n * column. Config views are shared and change only in\n * code — the runtime never mutates them.\n */\nexport function configViewsFor(\n collection: CollectionDef,\n pseudo: readonly string[] = [],\n): ResolvedView[] {\n const declared = collection.views\n if (!Array.isArray(declared)) return []\n const seen = new Set<string>()\n const resolved: ResolvedView[] = []\n declared.forEach((raw, index) => {\n const parsed = configViewSchema.safeParse(raw)\n if (!parsed.success) return\n const view = parsed.data\n const id = view.id ?? configViewId(view.name, index)\n if (seen.has(id)) return\n seen.add(id)\n // EC-444: `initial` supersedes the deprecated `default` alias (one-release window).\n const initial = view.initial ?? view.default\n const { columns, hidden } = resolveConfigColumns(collection, view.columns, pseudo)\n resolved.push({\n id,\n name: view.name,\n ...(initial ? { initial: true } : {}),\n state: normalizeViewState({\n filters: view.filters ?? [],\n sort: view.sort ?? null,\n columns,\n hidden,\n }),\n })\n })\n return resolved\n}\n\n/**\n * Does the collection declare a baseline-override view (a config view whose id is\n * {@link DEFAULT_VIEW_OVERRIDE_ID})? When true the synthesized \"All entries\" lens is\n * replaced by that entry verbatim (see {@link resolveCollectionViews}), EC-444.\n */\nexport function hasDefaultViewOverride(collection: CollectionDef): boolean {\n return configViewsFor(collection).some((view) => view.id === DEFAULT_VIEW_OVERRIDE_ID)\n}\n\n/**\n * The ordered view list a collection surfaces (EC-444): the baseline first, then the\n * config-declared views in declaration order. The baseline is either an authored\n * OVERRIDE (the config view whose id is {@link DEFAULT_VIEW_OVERRIDE_ID}, used\n * VERBATIM and NOT repeated among the trailing views) or, absent one, the\n * `synthesizedBaseline` the caller passes (the studio's translated \"All entries\"\n * lens). Pure — the store supplies the synthesized baseline (i18n-bound `name`).\n */\nexport function resolveCollectionViews(\n collection: CollectionDef,\n synthesizedBaseline: ResolvedView,\n pseudo: readonly string[] = [],\n): ResolvedView[] {\n const configViews = configViewsFor(collection, pseudo)\n const overrideIndex = configViews.findIndex((view) => view.id === DEFAULT_VIEW_OVERRIDE_ID)\n if (overrideIndex < 0) return [synthesizedBaseline, ...configViews]\n const override = configViews[overrideIndex]!\n const rest = configViews.filter((_, index) => index !== overrideIndex)\n return [override, ...rest]\n}\n\n/**\n * The ids of config views that still use the DEPRECATED `default` flag without the\n * new `initial` (EC-444). Drives the one-release deprecation warning (mirrors the\n * duplicate-default channel); empty once every view has migrated to `initial`.\n */\nexport function deprecatedDefaultFlagViewIds(collection: CollectionDef): string[] {\n const declared = collection.views\n if (!Array.isArray(declared)) return []\n const seen = new Set<string>()\n const ids: string[] = []\n declared.forEach((raw, index) => {\n const parsed = configViewSchema.safeParse(raw)\n if (!parsed.success) return\n const view = parsed.data\n const id = view.id ?? configViewId(view.name, index)\n if (seen.has(id)) return\n seen.add(id)\n if (view.default !== undefined && view.initial === undefined) ids.push(id)\n })\n return ids\n}\n\n/**\n * The id of the config view flagged `initial: true` (EC-343/EC-444; `default` read\n * as a deprecated alias) — the seed for a collection's INITIAL active view. When\n * several are flagged (a misconfiguration, reported by {@link configViewIssues}) the\n * FIRST in declaration order wins deterministically; when none is flagged the caller\n * falls back to the baseline lens. `undefined` when the collection flags none.\n */\nexport function defaultConfigViewId(collection: CollectionDef): string | undefined {\n return configViewsFor(collection).find((view) => view.initial)?.id\n}\n\n/** A config-level problem with a collection's declared views (EC-343/EC-444). */\nexport interface ConfigViewIssue {\n /** Stable code (kept from EC-343 to avoid catalog churn); reads \"duplicate initial\". */\n code: 'duplicate-default'\n message: string\n /** The offending view ids (all views flagged `initial`, in declaration order). */\n viewIds: string[]\n}\n\n/**\n * Validate a collection's config-declared views (EC-343/EC-444): at most one may set\n * `initial: true` (`default` counted as its deprecated alias). A duplicate is returned\n * as an explicit, structured issue — never silently swallowed — so the studio can\n * surface it (the first still wins deterministically for seeding, per\n * {@link defaultConfigViewId}). Pure and schema-only; the DOM-free counterpart of the\n * \"failures are first-class\" contract.\n */\nexport function configViewIssues(collection: CollectionDef): ConfigViewIssue[] {\n const initials = configViewsFor(collection).filter((view) => view.initial)\n if (initials.length <= 1) return []\n const viewIds = initials.map((view) => view.id)\n return [\n {\n code: 'duplicate-default',\n message: `Collection \"${collection.id}\" declares ${initials.length} initial views (${viewIds.join(', ')}); at most one view may set \\`initial: true\\`. Seeding \"${viewIds[0]}\".`,\n viewIds,\n },\n ]\n}\n\n/**\n * The default column order: the schema's title field first (it becomes the\n * default title/link column — EC-213 drops the separate primary-column\n * selector, treating the first visible column as the title), then the\n * remaining fields in schema order.\n */\nfunction orderedColumnNames(collection: CollectionDef, pseudo: readonly string[] = []): string[] {\n const names = collection.fields.map((field) => field.name)\n const title = titleFieldOf(collection)?.name\n const schemaOrdered =\n title === undefined || !names.includes(title)\n ? names\n : [title, ...names.filter((name) => name !== title)]\n // EC-445: the column UNIVERSE = schema fields, then the applicable reserved\n // pseudo-columns (they are NOT in `collection.fields`).\n return [...schemaOrdered, ...pseudo]\n}\n\n/** Deep-cloned canonical form (stable key order via the Zod shape). */\nexport function normalizeViewState(state: TableViewState): TableViewState {\n return tableViewStateSchema.parse(state)\n}\n\n/** Structural equality on normalized states — drives the \"unsaved changes\" affordance. */\nexport function viewStatesEqual(a: TableViewState, b: TableViewState): boolean {\n return JSON.stringify(normalizeViewState(a)) === JSON.stringify(normalizeViewState(b))\n}\n\n/** One column of a view resolved against the current schema (EC-213). */\nexport interface ResolvedColumn {\n /** The schema field name. */\n field: string\n /** Whether the column renders (`false` ⇒ in {@link TableViewState.hidden}). */\n visible: boolean\n}\n\n/**\n * Resolve a view's columns against the live schema (EC-213): every schema\n * field exactly once, in the view's saved order, with any fields the view\n * predates appended (visible) and any fields no longer in the schema dropped.\n * This is the single source of truth for \"which columns, in what order, shown\n * or hidden\" — order is preserved across hide/show because visibility lives in\n * `hidden`, never in the order.\n */\nexport function resolveColumns(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): ResolvedColumn[] {\n const schemaNames = collection.fields.map((field) => field.name)\n // EC-445: the valid universe to KEEP from the saved order is schema fields PLUS the\n // applicable pseudo-columns (which are not in `collection.fields`) — so a seeded\n // `$state`/`$url`/`$updatedAt` is preserved + ordered, never dropped as \"unknown\".\n const keep = new Set([...schemaNames, ...pseudo])\n const hidden = new Set(state.hidden)\n const inState = new Set(state.columns)\n // Keep the saved order, restricted to the live universe and de-duplicated (a\n // corrupted persisted state must never render one field as two columns).\n const ordered: string[] = []\n const seen = new Set<string>()\n for (const name of state.columns) {\n if (keep.has(name) && !seen.has(name)) {\n ordered.push(name)\n seen.add(name)\n }\n }\n // Append universe members the saved order predates: new schema fields (EC-213\n // discovery), then applicable pseudo-columns not yet placed (EC-445).\n const appended = [\n ...schemaNames.filter((name) => !seen.has(name)),\n ...pseudo.filter((name) => !seen.has(name)),\n ]\n return [...ordered, ...appended].map((field) => {\n // A freshly-appended opt-in pseudo-column ($publishedAt) starts hidden; once it\n // is in the saved order (an editor un-hid it) its visibility follows `hidden`.\n const defaultHiddenAppend = DEFAULT_HIDDEN_PSEUDO_COLUMNS.has(field) && !inState.has(field)\n return { field, visible: !hidden.has(field) && !defaultHiddenAppend }\n })\n}\n\n/** The visible columns of a view, in render order (EC-213). */\nexport function visibleColumns(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): string[] {\n return resolveColumns(collection, state, pseudo)\n .filter((column) => column.visible)\n .map((column) => column.field)\n}\n\n/**\n * The title/link column — the document IDENTITY column (EC-242): the schema title\n * field, shown as the leftmost linked cell whose content is `resolveDocumentTitle`\n * (a string `titleField` or a function pattern). Always present regardless of\n * column visibility — it is the document's identity, not a toggleable data column —\n * and excluded from the data columns so the title never shows twice. Falls back to\n * the first visible column, then the first field, then `id`, when no title field\n * is resolvable (e.g. a function title with no backing `title` field).\n */\nexport function primaryColumn(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): string {\n return (\n titleFieldOf(collection)?.name ??\n // EC-445: a pseudo-column is never the identity column (it has no title value) —\n // fall back to the first visible SCHEMA column.\n visibleColumns(collection, state, pseudo).find((name) => !isPseudoColumn(name)) ??\n collection.fields[0]?.name ??\n 'id'\n )\n}\n\n/**\n * Reconcile `columns` to the full resolved order so column edits operate on a\n * complete, stable order (drops removed fields, pins appended ones), and prune\n * `hidden` to fields the live schema still has (a column removed from the schema\n * must not leave dead `hidden` cruft that trips dirty-detection / persists).\n */\nfunction withResolvedOrder(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): TableViewState {\n const columns = resolveColumns(collection, state, pseudo).map((column) => column.field)\n const live = new Set(columns)\n const hidden = state.hidden.filter((name) => live.has(name))\n return { ...state, columns, hidden }\n}\n\n/**\n * The canonical, schema-resolved form of a view state — full column order with\n * `hidden` pruned to live fields (EC-213). Two states that render identically\n * share one canonical form, so dirty-detection never trips on a mere column\n * reconciliation or a stale `hidden` entry (only a real filter/sort/visibility/\n * order change counts as \"unsaved\").\n */\nexport function canonicalViewState(\n collection: CollectionDef,\n state: TableViewState,\n pseudo: readonly string[] = [],\n): TableViewState {\n return normalizeViewState(withResolvedOrder(collection, state, pseudo))\n}\n\n/**\n * Toggle a column's visibility — position is preserved (EC-213): visibility\n * lives in `hidden`, the order in `columns` is untouched. Columns the saved\n * order predates are pinned into `columns` first so their place is stable.\n */\nexport function toggleColumn(\n collection: CollectionDef,\n state: TableViewState,\n field: string,\n pseudo: readonly string[] = [],\n): TableViewState {\n const base = withResolvedOrder(collection, state, pseudo)\n const hidden = base.hidden.includes(field)\n ? base.hidden.filter((name) => name !== field)\n : [...base.hidden, field]\n return { ...base, hidden }\n}\n\n/** Move a column one position left (-1) or right (+1) in the full column order. */\nexport function moveColumn(\n collection: CollectionDef,\n state: TableViewState,\n field: string,\n delta: -1 | 1,\n pseudo: readonly string[] = [],\n): TableViewState {\n const base = withResolvedOrder(collection, state, pseudo)\n const from = base.columns.indexOf(field)\n const to = from + delta\n if (from < 0 || to < 0 || to >= base.columns.length) return state\n const columns = [...base.columns]\n columns.splice(from, 1)\n columns.splice(to, 0, field)\n return { ...base, columns }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-writes.js","sourceRoot":"","sources":["../../../../src/lib/collection-view/__fixtures__/document-writes.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;QAC7B,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;QAChB,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ;QACrB,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;QACnB,eAAe,EAAE,GAAG,EAAE,GAAE,CAAC;QACzB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;QACvB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;QACjB,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;QACxB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;QACvB,iBAAiB,EAAE,cAAc;KAClC,CAAA;AACH,CAAC","sourcesContent":["import type { DocumentWrites } from '../collection-view-source'\n\n/**\n * A no-op revisioned-document write model (EC-595 A2) for surface tests that render a\n * CMS-shaped source with `renderToStaticMarkup` and never write.\n */\nexport function noopDocumentWrites(): DocumentWrites {\n return {\n kind: 'document',\n commit: async () => undefined,\n revisionOf: () => undefined,\n insert: () => {},\n newId: () => 'new-id',\n conflicts: () => [],\n resolveConflict: () => {},\n adoptSnapshot: () => {},\n flush: async () => {},\n replace: () => {},\n subscribe: () => () => {},\n reportPresence: () => {},\n clearPresence: () => {},\n presenceSessionId: 'test-session',\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"document-writes.js","sourceRoot":"","sources":["../../../../src/lib/collection-view/__fixtures__/document-writes.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;QAC7B,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,cAAc,EAAE,GAAG,EAAE,CAAC,SAAS;QAC/B,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;QAChB,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ;QACrB,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;QACnB,eAAe,EAAE,GAAG,EAAE,GAAE,CAAC;QACzB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;QACvB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;QACjB,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;QACxB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;QACvB,iBAAiB,EAAE,cAAc;KAClC,CAAA;AACH,CAAC","sourcesContent":["import type { DocumentWrites } from '../collection-view-source'\n\n/**\n * A no-op revisioned-document write model (EC-595 A2) for surface tests that render a\n * CMS-shaped source with `renderToStaticMarkup` and never write.\n */\nexport function noopDocumentWrites(): DocumentWrites {\n return {\n kind: 'document',\n commit: async () => undefined,\n revisionOf: () => undefined,\n revisionOfView: () => undefined,\n insert: () => {},\n newId: () => 'new-id',\n conflicts: () => [],\n resolveConflict: () => {},\n adoptSnapshot: () => {},\n flush: async () => {},\n replace: () => {},\n subscribe: () => () => {},\n reportPresence: () => {},\n clearPresence: () => {},\n presenceSessionId: 'test-session',\n }\n}\n"]}
|
|
@@ -201,11 +201,19 @@ export interface DocumentWrites {
|
|
|
201
201
|
readonly kind: 'document';
|
|
202
202
|
/**
|
|
203
203
|
* Commit the patches a writer made; resolves once acknowledged (`undefined` in a
|
|
204
|
-
* fixture session). `bases` — per patch
|
|
204
|
+
* fixture session). `bases` — REQUIRED, per patch: the revision of the view the writer
|
|
205
|
+
* authored it against (EC-647 — never the session's current one by default; a write
|
|
206
|
+
* that names none is refused).
|
|
205
207
|
*/
|
|
206
|
-
commit(ref: DocumentRef, patches: readonly DocumentPatch[], bases
|
|
207
|
-
/** The revision the session's view of a document is at. */
|
|
208
|
+
commit(ref: DocumentRef, patches: readonly DocumentPatch[], bases: readonly (number | undefined)[]): Promise<CommitOutcome | undefined>;
|
|
209
|
+
/** The revision the session's view of a document is at now. */
|
|
208
210
|
revisionOf(ref: DocumentRef): number | undefined;
|
|
211
|
+
/**
|
|
212
|
+
* EC-647 — the revision a document value the session SHOWED is at (`undefined` for a
|
|
213
|
+
* value it never showed, or a provisional one): a writer holding the value it displayed
|
|
214
|
+
* holds its revision.
|
|
215
|
+
*/
|
|
216
|
+
revisionOfView(view: CmsDocument): number | undefined;
|
|
209
217
|
/** Create a document from a whole value (insert-if-absent): duplicate. */
|
|
210
218
|
insert(doc: CmsDocument): void;
|
|
211
219
|
/** A fresh document id from the session's injected factory (EC-578). */
|
|
@@ -218,11 +226,11 @@ export interface DocumentWrites {
|
|
|
218
226
|
/** The forced flush's persistence half: await every queued write of the document. */
|
|
219
227
|
flush(ref: DocumentRef): Promise<void>;
|
|
220
228
|
/**
|
|
221
|
-
* Write the whole document at the revision the
|
|
222
|
-
* the value-position grammar has no position
|
|
223
|
-
* is refused, never overwritten.
|
|
229
|
+
* Write the whole document at `revision` — the revision of the view the snapshot was
|
|
230
|
+
* authored on (EC-647; a document-level key the value-position grammar has no position
|
|
231
|
+
* for — the slot `alias`). A move since is refused, never overwritten.
|
|
224
232
|
*/
|
|
225
|
-
replace(doc: CmsDocument): void;
|
|
233
|
+
replace(doc: CmsDocument, revision: number | undefined): void;
|
|
226
234
|
/**
|
|
227
235
|
* EC-595 point 7 — follow ONE document while it is open: every pushed row is adopted
|
|
228
236
|
* under the local edits (the editor rebases), and the presence on it is delivered to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-view-source.js","sourceRoot":"","sources":["../../../src/lib/collection-view/collection-view-source.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAySvD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA4B,EAC5B,KAAe,EACf,MAAoB;IAEpB,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACjG,CAAC;AAyDD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA4B;IACjE,OAAO,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS;QAC3C,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO;KACtC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type {\n CmsDocument,\n CollectionDef,\n DocumentPatch,\n DocumentRef,\n ValuePath,\n DocumentUrl,\n FieldDef,\n Locale,\n LocaleConfig,\n LocalizedString,\n RestoreScope,\n} from '@elytracms/core/cms-core'\nimport type { CmsValidationIssue } from '@elytracms/core/cms-core'\nimport type { OperationError } from '@elytracms/core/operations'\nimport type { CmsDocumentRecord, PresenceEntry, ReferenceTarget } from '@elytracms/core/persistence'\nimport type { CommitOutcome, DocumentConflict } from '../operations/cms-persistence'\nimport type { TableViewState } from '../cms-views/view-model'\nimport { pseudoColumns } from '../cms-views/view-model'\nimport type { ReadState } from '../query'\n// The concrete inline-edit + bulk vocabulary (Stream A relocates it into `lib` as it settles).\nimport type { CellCommitInput, CellCommitOutcome } from '../../components/cms/cell-edit'\nimport type { BulkAction, BulkReport, BulkSetField } from '../../components/cms/bulk-actions'\nimport type { DocumentVersionsView, ImportReport } from '../../components/cms/cms-store'\n\n/**\n * `CollectionViewSource` — the studio's UNIVERSAL interaction seam (EC-240,\n * vision AD-19).\n *\n * The list surface (`CollectionTable`) and the edit-shell (`DetailEditor`) are\n * the studio's universal interaction surfaces. Historically they read the\n * concrete `CmsStore` through `useCms()`, so they only served `cmsDocuments`.\n * This interface is the data-agnostic seam they render over instead, so the SAME\n * surfaces drive the users rail (EC-240), redirects (EC-303), the Components app\n * edit-shell, and any future rail — no hand-rolled UI per rail.\n *\n * **Shape:** the source is scoped to ONE collection (it carries `schema` +\n * `collectionId`), and its methods mirror the subset of `CmsStore` the surfaces\n * actually use — dropping the `collectionId` argument (the source already knows\n * it). Keeping the names/signatures aligned makes the CMS adapter a\n * behaviour-preserving pass-through and the migration near-mechanical.\n *\n * **Referential stability:** the surfaces put `documents`, `isPublished`,\n * `localeConfig`, etc. in `useMemo` dependency arrays. An implementation MUST\n * return stable references across renders (delegate to the underlying store's\n * already-stable methods; never wrap in a fresh closure each render) or memos\n * bust and the inline-edit order snapshot / perf regress.\n *\n * **Capabilities:** flags gate whole shell regions AND method presence — a source\n * with `capabilities.versions === false` (the users rail) never mounts the\n * Versions pane, so no `listVersions` read fires on credential records. Optional\n * method groups are present iff the flag is set.\n */\nexport interface CollectionViewSource {\n /** The rail/collection this source serves. */\n readonly collectionId: string\n /** The schema lens: fields, form tabs/groups, `titleField`, display nouns. */\n readonly schema: CollectionDef\n /** Which regions/methods this source supports. */\n readonly capabilities: CollectionViewCapabilities\n\n /** The project scope (asset picker, published-pool queries). Absent in fixture sessions. */\n readonly projectId?: string\n /**\n * The collection id assets live in (for a cell/field's `titleOf` label fallback\n * when {@link resolveAsset} finds no record). Present only for sources that\n * reference assets — a rail without assets (users) omits it.\n */\n readonly assetCollectionId?: string\n /** The ambient locale lens (only meaningful when `capabilities.locales`). */\n readonly localeConfig: LocaleConfig\n readonly activeLocale: Locale\n\n // --- Reads -----------------------------------------------------------------\n /** The full row set (view mechanics filter/sort this client-side). */\n documents(): CmsDocument[]\n get(ref: DocumentRef): CmsDocument | undefined\n /** A relation/asset target's display title (hides the string-vs-function `titleField`). */\n titleOf(ref: DocumentRef): string\n /**\n * List the candidate records of a relation field's declared `target` collection\n * — the pick-list for a relation picker (EC-072). References are first-class and\n * collection-based: the field's schema declares which collection(s) it targets,\n * and this resolves those rows for ANY target (cross-collection), not just this\n * source's own collection. The caller passes `field.target`; a multi-target field\n * (future) merges one call per declared target. An unknown/empty target yields `[]`.\n */\n referenceCandidates(collectionId: string): CmsDocument[]\n /**\n * The workspace schema a reference/asset can point at — the schema counterpart to\n * {@link referenceCandidates}. Needed for the cases that read a TARGET collection's\n * fields (an asset field editing the asset collection's own metadata; the reuse\n * capability correlating embed manifests against their target collection). A\n * reference is collection-based, so resolving one sometimes needs the target's\n * schema, not just its rows.\n */\n readonly collections: readonly CollectionDef[]\n isFieldReadOnly(field: FieldDef): boolean\n /**\n * Principal-based field access (EC-240, vision AD-18): `edit` (writable), `read`\n * (visible but read-only), or `hidden` (not rendered for this principal). This is\n * IDENTITY-driven and distinct from a field's content-conditional `hidden(values)`\n * — e.g. an editor's own `role` resolves to `read`, a viewer never SEES a\n * sensitive field (`hidden`). A single tri-state (never two independent flags) so\n * the nonsensical writable-but-invisible state can't be expressed. Optional:\n * absent ⇒ derived from {@link isFieldReadOnly} (`read`|`edit`), i.e. default-open\n * (permissions RESTRICT, never grant a baseline). Per-rail policy lives on the\n * source; the starter's policy flows into its construction (engine = mechanism).\n * Prefer {@link resolveFieldAccess} over calling this directly (it applies the\n * default-open fallback).\n */\n fieldAccess?(field: FieldDef, record?: CmsDocument): FieldAccess\n validate(doc: CmsDocument): CmsValidationIssue[]\n /**\n * Resolve an asset id to its display metadata for a cell/field, or `undefined`\n * when there is no asset backend (a source without assets degrades to a label\n * via {@link titleOf}, matching today's \"no AssetsProvider\" behaviour).\n */\n resolveAsset?(id: string): AssetDisplay | undefined\n /**\n * How this rail's records are addressed in the EC-155 reference index — the\n * target shape the delete/unpublish confirmation's inbound pre-flight queries\n * (EC-433). Absent ⇒ the document shape (`{ type: 'document', id: 'collection:id' }`),\n * which every `cmsDocuments` collection uses. The assets rail supplies\n * `{ type: 'asset' }` so its list/bulk delete confirmation enumerates the SAME\n * inbound references its detail surface does — a document-shaped lookup would\n * report a referenced asset as \"not referenced\" (the EC-319 objection that\n * originally kept `remove` off the assets rail).\n */\n referenceTarget?(ref: DocumentRef): ReferenceTarget\n /** The last failed/denied mutation, surfaced by the shell (never a silent failure). */\n readonly lastError: OperationError | null\n clearLastError(): void\n /**\n * Land any queued/optimistic writes so a subsequent pre-flight READ sees them\n * (the reference index is maintained on write). A source with no async\n * persistence omits it — its reads are already authoritative.\n */\n flush?(): Promise<void>\n\n /**\n * The studio route splat for a record's detail surface (the row link + the\n * post-create navigation target), e.g. `studioPath.cmsDocument(collectionId, id)`.\n * Rail-owned so the list never hard-codes the CMS route. `undefined` ⇒ the rail\n * has no detail surface, so rows render as plain text (no navigation).\n */\n detailPath?(id: string): string\n /**\n * The studio route splat for this rail's LIST surface — the edit shell's\n * \"back to list\" breadcrumb crumb and its post-delete navigation target, e.g.\n * `studioPath.cmsCollection(collectionId)`. Rail-owned so the edit shell never\n * hard-codes the CMS route (the counterpart to {@link detailPath}). `undefined`\n * ⇒ the crumb is unlinked and delete falls back to the project index.\n */\n readonly listPath?: string\n\n // --- View state (list) -----------------------------------------------------\n viewState(): TableViewState\n setViewState(update: TableViewState | ((prev: TableViewState) => TableViewState)): void\n\n // --- Writes ----------------------------------------------------------------\n create(): DocumentRef\n /**\n * EC-595 A2 — HOW this source's records are written: exactly one model per source,\n * so a surface can never write a revisioned document the record way or vice versa.\n * `record` — the explicit-save rails (users, redirects, assets, the account): the\n * editor's Save button hands the whole record over. `document` — the CMS: every\n * writer emits patches at its source, committed on quiescence and merged per path\n * at the store; the editor shows per-field conflicts and follows the subscription.\n */\n readonly writes: CollectionWrites\n remove(ref: DocumentRef): void\n /**\n * Bulk publish/unpublish/delete/set-field (only when `capabilities.bulk`): one\n * command PER item, per-item outcomes enumerated in the report (partial failure\n * is never silent).\n */\n bulk?(ids: readonly string[], action: BulkAction, setField?: BulkSetField): Promise<BulkReport>\n\n // --- Capability method groups (present iff the matching flag is set) --------\n /** `publish` — published-pool predicate + publish/unpublish. */\n readonly publishing?: PublishingCapability\n /**\n * Per-document timestamps (EC-445) — the data behind the `$updatedAt`\n * pseudo-column (and, once its data path lands, `$publishedAt`). Present iff the\n * source materializes them (the CMS source, sourced through session-hydration);\n * a rail that carries no timestamps omits it, so those pseudo-columns simply don't\n * apply (see {@link pseudoColumnsForSource}). The accessor shape mirrors\n * {@link PublishingCapability.isPublished} — a per-ref lookup, referentially stable.\n */\n readonly timestamps?: DocumentTimestampsCapability\n /** `versions` — version history + restore. */\n readonly versioning?: VersioningCapability\n /** `inlineEdit` — the list's single-command optimistic cell write. */\n readonly inlineEditing?: InlineEditCapability\n /**\n * Config-as-code named lenses (EC-246b) the header view selector switches\n * between. Optional: a source that declares no named views (a non-CMS rail\n * like users) omits it, and the selector renders nothing (single default).\n */\n readonly views?: NamedViewsCapability\n /**\n * `importExport` — JSON round-trip of the collection's records. CMS-specific;\n * a rail whose records are credential-bearing (users) omits it, so neither the\n * import dialog nor the export action mounts (identities aren't dumped to JSON).\n */\n readonly imports?: ImportCapability\n}\n\n/** EC-595 A2 — the write model of a source (see {@link CollectionViewSource.writes}). */\nexport type CollectionWrites = RecordWrites | DocumentWrites\n\n/**\n * An explicit-save rail: the editor's Save button writes the record. `base` (EC-616) is the\n * record as the editor OPENED it (or as of their last successful save) — a rail that can\n * write per column sends only what differs from it, so a column another writer changed\n * meanwhile is kept; absent for a record being created.\n */\nexport interface RecordWrites {\n readonly kind: 'record'\n save(doc: CmsDocument, base?: CmsDocument): void\n}\n\n/**\n * The revisioned-document write model (EC-595, ratified 2026-10-24): patches at the\n * source, the persister's queue, per-field conflicts, the document subscription.\n */\nexport interface DocumentWrites {\n readonly kind: 'document'\n /**\n * Commit the patches a writer made; resolves once acknowledged (`undefined` in a\n * fixture session). `bases` — per patch, the revision the edit was started at.\n */\n commit(\n ref: DocumentRef,\n patches: readonly DocumentPatch[],\n bases?: readonly (number | undefined)[],\n ): Promise<CommitOutcome | undefined>\n /** The revision the session's view of a document is at. */\n revisionOf(ref: DocumentRef): number | undefined\n /** Create a document from a whole value (insert-if-absent): duplicate. */\n insert(doc: CmsDocument): void\n /** A fresh document id from the session's injected factory (EC-578). */\n newId(): string\n /** The open per-field conflicts on a document. */\n conflicts(ref: DocumentRef): readonly DocumentConflict[]\n resolveConflict(ref: DocumentRef, conflictId: string, choice: 'theirs' | 'mine'): void\n /** Adopt a row the document subscription pushed (local edits win on their paths until flushed). */\n adoptSnapshot(ref: DocumentRef, record: CmsDocumentRecord | undefined): void\n /** The forced flush's persistence half: await every queued write of the document. */\n flush(ref: DocumentRef): Promise<void>\n /**\n * Write the whole document at the revision the session holds (a document-level key\n * the value-position grammar has no position for — the slot `alias`). A move since\n * is refused, never overwritten.\n */\n replace(doc: CmsDocument): void\n /**\n * EC-595 point 7 — follow ONE document while it is open: every pushed row is adopted\n * under the local edits (the editor rebases), and the presence on it is delivered to\n * `onPresence`. Returns the unsubscribe function.\n */\n subscribe(ref: DocumentRef, onPresence: (presence: readonly PresenceEntry[]) => void): () => void\n /** Thin presence (Stage A): this session is on the document, in `path`'s field (or on no field). */\n reportPresence(ref: DocumentRef, path: ValuePath | undefined): void\n /** This session left the document. */\n clearPresence(ref: DocumentRef): void\n /** This session's presence id (one per tab), so the editor can leave itself out. */\n readonly presenceSessionId: string\n}\n\n/**\n * The capability matrix. Each flag gates a shell region AND the presence of its\n * method group. The **users rail** (EC-240) sets `publish:false`, `versions:false`\n * (credential caution), `create:false` (identity minted by sign-up), and no\n * `liveUrl`/`hierarchy`.\n */\nexport interface CollectionViewCapabilities {\n readonly publish: boolean\n readonly versions: boolean\n readonly locales: boolean\n readonly inlineEdit: boolean\n readonly create: boolean\n /**\n * Duplicate-document action (EC-442, amended same day). Deliberately its own\n * flag, never derived from `create`: the owner call (2026-07-17) is CMS\n * collections ONLY — no primitive rail offers Duplicate for now (identities\n * and uploads aren't copyable content; redirects deferred until requested as\n * a product feature).\n */\n readonly duplicate: boolean\n readonly remove: boolean\n readonly bulk: boolean\n /** The derived live-URL column (published pool × deployment routes). */\n readonly liveUrl: boolean\n /** Parent-self-relation tree mode (hierarchical collections only). */\n readonly hierarchy: boolean\n /** JSON import/export of the collection's records (off for credential rails). */\n readonly importExport: boolean\n /**\n * The rail is administration-scoped (mirrors `ADMIN_ONLY_OPERATIONS`). The\n * nav-permission layer reads this to gate the rail item. Absent ⇒ not admin-only.\n */\n readonly adminOnly?: boolean\n}\n\n/**\n * Principal-based field access (EC-240, AD-18). One tri-state drives BOTH visibility\n * and writability: `edit` (writable), `read` (visible, read-only), `hidden` (not\n * rendered). Default `edit` (default-open). Distinct from content-`hidden(values)`;\n * they compose — a field shows iff *not content-hidden AND access ≠ hidden*, and is\n * editable iff *access = edit AND not otherwise read-only* (published view, `form.readOnly`).\n */\nexport type FieldAccess = 'edit' | 'read' | 'hidden'\n\n/**\n * Resolve a field's effective principal access for a source — its {@link\n * CollectionViewSource.fieldAccess} policy when present, else derived from the\n * boolean `isFieldReadOnly` (default-open). The one place the shell asks \"may this\n * principal edit / see this field?\", so the default-open fallback lives in one spot.\n */\nexport function resolveFieldAccess(\n source: CollectionViewSource,\n field: FieldDef,\n record?: CmsDocument,\n): FieldAccess {\n return source.fieldAccess?.(field, record) ?? (source.isFieldReadOnly(field) ? 'read' : 'edit')\n}\n\n/**\n * Asset display metadata a cell/field renders (thumbnail or labelled badge). EC-587:\n * named apart from core's `ResolvedAsset` (the delivery shape) — this is the studio's\n * label/thumbnail slice; its `alt` is the one reader's (`assetAlt`).\n */\nexport interface AssetDisplay {\n readonly url?: string\n readonly contentType?: string\n readonly title?: string\n readonly filename?: string\n readonly alt?: string\n}\n\n/** `publish` capability. */\nexport interface PublishingCapability {\n /** Published-ness from the version pointer (NOT a row field). */\n isPublished(ref: DocumentRef): boolean\n /**\n * Does this PUBLISHED document's working draft carry unpublished changes\n * (EC-449)? The cheap per-row signal behind the amber \"changed\" `$state` dot —\n * sourced from the MATERIALIZED `hasUnpublishedChanges` record flag (computed\n * once at the write chokepoint), never a per-row snapshot compare. Optional: a\n * source without the signal omits it, and the list derives only\n * published/draft (exactly the pre-EC-449 rendering). Same referentially-stable\n * per-ref accessor shape as {@link isPublished}.\n */\n hasUnpublishedChanges?(ref: DocumentRef): boolean\n publish(ref: DocumentRef): Promise<void>\n unpublish(ref: DocumentRef): Promise<void>\n /**\n * Live URLs for the routable documents, keyed by id — derived from the\n * PUBLISHED pool (never draft rows) so an unpublished slug/parent edit can't\n * leak into a live link (EC-205/EC-216). `null` when the collection is not\n * routable → the live-URL column is hidden. Only present when `capabilities.liveUrl`.\n *\n * EC-628: a {@link ReadState} — the URL map only when the published read answered; a\n * failed read is `error` with its sentence, which the URL column shows in every row\n * (never the \"not published\" dash an empty map would give).\n */\n liveUrls?(): ReadState<ReadonlyMap<string, DocumentUrl>> | null\n}\n\n/**\n * `timestamps` capability (EC-445/EC-447): per-document record timestamps as ISO\n * strings, or `undefined` when a document carries none. The `$updatedAt`/`$publishedAt`\n * pseudo-columns read + sort by these. `updatedAt` is the last-write instant;\n * `publishedAt` (EC-447) is the FIRST-publish instant — set-once on publish, cleared on\n * unpublish, so it is `undefined` for a draft / never-published / currently-unpublished\n * document (the column shows EmDash).\n */\nexport interface DocumentTimestampsCapability {\n updatedAt(ref: DocumentRef): string | undefined\n publishedAt(ref: DocumentRef): string | undefined\n}\n\n/**\n * The reserved pseudo-columns applicable to a source's list (EC-445), derived from\n * its capabilities: `$updatedAt` iff it materializes timestamps, `$state` iff it has a\n * publish lifecycle, `$url` iff it resolves delivery URLs. The one place the list\n * surface + the Display picker agree on which pseudo-columns exist for a source, so\n * the column universe never drifts between where columns render and where they toggle.\n */\nexport function pseudoColumnsForSource(source: CollectionViewSource): string[] {\n return pseudoColumns(source.schema, {\n timestamps: source.timestamps !== undefined,\n publishing: source.publishing !== undefined,\n routable: source.capabilities.liveUrl,\n })\n}\n\n/** `versions` capability. */\nexport interface VersioningCapability {\n restore(ref: DocumentRef, version: number, scope?: RestoreScope): Promise<CmsDocument | null>\n /**\n * The document's recorded version history + live pin. Folds the flush-before-read\n * ordering INTO the loader (the adapter's concern), so every fetch lists an\n * authoritative history regardless of which surface triggered the change (EC-224).\n */\n load(ref: DocumentRef): Promise<DocumentVersionsView>\n}\n\n/** `inlineEdit` capability: the list's single-command optimistic cell write (EC-168). */\nexport interface InlineEditCapability {\n commitField(input: CellCommitInput): Promise<CellCommitOutcome>\n}\n\n/** A named lens the header selector offers — id + display name only (the header never needs its state). */\nexport interface NamedView {\n readonly id: string\n /** Display name; a {@link LocalizedString} (EC-343), resolved at the render site like `form.label`. */\n readonly name: LocalizedString\n}\n\n/** `importExport` capability: validate + fold external JSON records into the collection (EC-079). */\nexport interface ImportCapability {\n importDocuments(items: unknown[]): ImportReport\n}\n\n/**\n * `views` capability: config-as-code named lenses (EC-246b). The header selector\n * only *picks* a lens — it never creates/edits/deletes one (shared views are code).\n */\nexport interface NamedViewsCapability {\n /** The built-in default + config-declared named views. */\n list(): readonly NamedView[]\n /** The currently-selected view id. */\n activeId(): string\n /** Switch views (resets the working table state to the view's baseline). */\n setActive(id: string): void\n}\n\nexport type { CellCommitInput, CellCommitOutcome, ImportReport }\n"]}
|
|
1
|
+
{"version":3,"file":"collection-view-source.js","sourceRoot":"","sources":["../../../src/lib/collection-view/collection-view-source.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAiTvD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA4B,EAC5B,KAAe,EACf,MAAoB;IAEpB,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACjG,CAAC;AAyDD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA4B;IACjE,OAAO,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS;QAC3C,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO;KACtC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type {\n CmsDocument,\n CollectionDef,\n DocumentPatch,\n DocumentRef,\n ValuePath,\n DocumentUrl,\n FieldDef,\n Locale,\n LocaleConfig,\n LocalizedString,\n RestoreScope,\n} from '@elytracms/core/cms-core'\nimport type { CmsValidationIssue } from '@elytracms/core/cms-core'\nimport type { OperationError } from '@elytracms/core/operations'\nimport type { CmsDocumentRecord, PresenceEntry, ReferenceTarget } from '@elytracms/core/persistence'\nimport type { CommitOutcome, DocumentConflict } from '../operations/cms-persistence'\nimport type { TableViewState } from '../cms-views/view-model'\nimport { pseudoColumns } from '../cms-views/view-model'\nimport type { ReadState } from '../query'\n// The concrete inline-edit + bulk vocabulary (Stream A relocates it into `lib` as it settles).\nimport type { CellCommitInput, CellCommitOutcome } from '../../components/cms/cell-edit'\nimport type { BulkAction, BulkReport, BulkSetField } from '../../components/cms/bulk-actions'\nimport type { DocumentVersionsView, ImportReport } from '../../components/cms/cms-store'\n\n/**\n * `CollectionViewSource` — the studio's UNIVERSAL interaction seam (EC-240,\n * vision AD-19).\n *\n * The list surface (`CollectionTable`) and the edit-shell (`DetailEditor`) are\n * the studio's universal interaction surfaces. Historically they read the\n * concrete `CmsStore` through `useCms()`, so they only served `cmsDocuments`.\n * This interface is the data-agnostic seam they render over instead, so the SAME\n * surfaces drive the users rail (EC-240), redirects (EC-303), the Components app\n * edit-shell, and any future rail — no hand-rolled UI per rail.\n *\n * **Shape:** the source is scoped to ONE collection (it carries `schema` +\n * `collectionId`), and its methods mirror the subset of `CmsStore` the surfaces\n * actually use — dropping the `collectionId` argument (the source already knows\n * it). Keeping the names/signatures aligned makes the CMS adapter a\n * behaviour-preserving pass-through and the migration near-mechanical.\n *\n * **Referential stability:** the surfaces put `documents`, `isPublished`,\n * `localeConfig`, etc. in `useMemo` dependency arrays. An implementation MUST\n * return stable references across renders (delegate to the underlying store's\n * already-stable methods; never wrap in a fresh closure each render) or memos\n * bust and the inline-edit order snapshot / perf regress.\n *\n * **Capabilities:** flags gate whole shell regions AND method presence — a source\n * with `capabilities.versions === false` (the users rail) never mounts the\n * Versions pane, so no `listVersions` read fires on credential records. Optional\n * method groups are present iff the flag is set.\n */\nexport interface CollectionViewSource {\n /** The rail/collection this source serves. */\n readonly collectionId: string\n /** The schema lens: fields, form tabs/groups, `titleField`, display nouns. */\n readonly schema: CollectionDef\n /** Which regions/methods this source supports. */\n readonly capabilities: CollectionViewCapabilities\n\n /** The project scope (asset picker, published-pool queries). Absent in fixture sessions. */\n readonly projectId?: string\n /**\n * The collection id assets live in (for a cell/field's `titleOf` label fallback\n * when {@link resolveAsset} finds no record). Present only for sources that\n * reference assets — a rail without assets (users) omits it.\n */\n readonly assetCollectionId?: string\n /** The ambient locale lens (only meaningful when `capabilities.locales`). */\n readonly localeConfig: LocaleConfig\n readonly activeLocale: Locale\n\n // --- Reads -----------------------------------------------------------------\n /** The full row set (view mechanics filter/sort this client-side). */\n documents(): CmsDocument[]\n get(ref: DocumentRef): CmsDocument | undefined\n /** A relation/asset target's display title (hides the string-vs-function `titleField`). */\n titleOf(ref: DocumentRef): string\n /**\n * List the candidate records of a relation field's declared `target` collection\n * — the pick-list for a relation picker (EC-072). References are first-class and\n * collection-based: the field's schema declares which collection(s) it targets,\n * and this resolves those rows for ANY target (cross-collection), not just this\n * source's own collection. The caller passes `field.target`; a multi-target field\n * (future) merges one call per declared target. An unknown/empty target yields `[]`.\n */\n referenceCandidates(collectionId: string): CmsDocument[]\n /**\n * The workspace schema a reference/asset can point at — the schema counterpart to\n * {@link referenceCandidates}. Needed for the cases that read a TARGET collection's\n * fields (an asset field editing the asset collection's own metadata; the reuse\n * capability correlating embed manifests against their target collection). A\n * reference is collection-based, so resolving one sometimes needs the target's\n * schema, not just its rows.\n */\n readonly collections: readonly CollectionDef[]\n isFieldReadOnly(field: FieldDef): boolean\n /**\n * Principal-based field access (EC-240, vision AD-18): `edit` (writable), `read`\n * (visible but read-only), or `hidden` (not rendered for this principal). This is\n * IDENTITY-driven and distinct from a field's content-conditional `hidden(values)`\n * — e.g. an editor's own `role` resolves to `read`, a viewer never SEES a\n * sensitive field (`hidden`). A single tri-state (never two independent flags) so\n * the nonsensical writable-but-invisible state can't be expressed. Optional:\n * absent ⇒ derived from {@link isFieldReadOnly} (`read`|`edit`), i.e. default-open\n * (permissions RESTRICT, never grant a baseline). Per-rail policy lives on the\n * source; the starter's policy flows into its construction (engine = mechanism).\n * Prefer {@link resolveFieldAccess} over calling this directly (it applies the\n * default-open fallback).\n */\n fieldAccess?(field: FieldDef, record?: CmsDocument): FieldAccess\n validate(doc: CmsDocument): CmsValidationIssue[]\n /**\n * Resolve an asset id to its display metadata for a cell/field, or `undefined`\n * when there is no asset backend (a source without assets degrades to a label\n * via {@link titleOf}, matching today's \"no AssetsProvider\" behaviour).\n */\n resolveAsset?(id: string): AssetDisplay | undefined\n /**\n * How this rail's records are addressed in the EC-155 reference index — the\n * target shape the delete/unpublish confirmation's inbound pre-flight queries\n * (EC-433). Absent ⇒ the document shape (`{ type: 'document', id: 'collection:id' }`),\n * which every `cmsDocuments` collection uses. The assets rail supplies\n * `{ type: 'asset' }` so its list/bulk delete confirmation enumerates the SAME\n * inbound references its detail surface does — a document-shaped lookup would\n * report a referenced asset as \"not referenced\" (the EC-319 objection that\n * originally kept `remove` off the assets rail).\n */\n referenceTarget?(ref: DocumentRef): ReferenceTarget\n /** The last failed/denied mutation, surfaced by the shell (never a silent failure). */\n readonly lastError: OperationError | null\n clearLastError(): void\n /**\n * Land any queued/optimistic writes so a subsequent pre-flight READ sees them\n * (the reference index is maintained on write). A source with no async\n * persistence omits it — its reads are already authoritative.\n */\n flush?(): Promise<void>\n\n /**\n * The studio route splat for a record's detail surface (the row link + the\n * post-create navigation target), e.g. `studioPath.cmsDocument(collectionId, id)`.\n * Rail-owned so the list never hard-codes the CMS route. `undefined` ⇒ the rail\n * has no detail surface, so rows render as plain text (no navigation).\n */\n detailPath?(id: string): string\n /**\n * The studio route splat for this rail's LIST surface — the edit shell's\n * \"back to list\" breadcrumb crumb and its post-delete navigation target, e.g.\n * `studioPath.cmsCollection(collectionId)`. Rail-owned so the edit shell never\n * hard-codes the CMS route (the counterpart to {@link detailPath}). `undefined`\n * ⇒ the crumb is unlinked and delete falls back to the project index.\n */\n readonly listPath?: string\n\n // --- View state (list) -----------------------------------------------------\n viewState(): TableViewState\n setViewState(update: TableViewState | ((prev: TableViewState) => TableViewState)): void\n\n // --- Writes ----------------------------------------------------------------\n create(): DocumentRef\n /**\n * EC-595 A2 — HOW this source's records are written: exactly one model per source,\n * so a surface can never write a revisioned document the record way or vice versa.\n * `record` — the explicit-save rails (users, redirects, assets, the account): the\n * editor's Save button hands the whole record over. `document` — the CMS: every\n * writer emits patches at its source, committed on quiescence and merged per path\n * at the store; the editor shows per-field conflicts and follows the subscription.\n */\n readonly writes: CollectionWrites\n remove(ref: DocumentRef): void\n /**\n * Bulk publish/unpublish/delete/set-field (only when `capabilities.bulk`): one\n * command PER item, per-item outcomes enumerated in the report (partial failure\n * is never silent).\n */\n bulk?(ids: readonly string[], action: BulkAction, setField?: BulkSetField): Promise<BulkReport>\n\n // --- Capability method groups (present iff the matching flag is set) --------\n /** `publish` — published-pool predicate + publish/unpublish. */\n readonly publishing?: PublishingCapability\n /**\n * Per-document timestamps (EC-445) — the data behind the `$updatedAt`\n * pseudo-column (and, once its data path lands, `$publishedAt`). Present iff the\n * source materializes them (the CMS source, sourced through session-hydration);\n * a rail that carries no timestamps omits it, so those pseudo-columns simply don't\n * apply (see {@link pseudoColumnsForSource}). The accessor shape mirrors\n * {@link PublishingCapability.isPublished} — a per-ref lookup, referentially stable.\n */\n readonly timestamps?: DocumentTimestampsCapability\n /** `versions` — version history + restore. */\n readonly versioning?: VersioningCapability\n /** `inlineEdit` — the list's single-command optimistic cell write. */\n readonly inlineEditing?: InlineEditCapability\n /**\n * Config-as-code named lenses (EC-246b) the header view selector switches\n * between. Optional: a source that declares no named views (a non-CMS rail\n * like users) omits it, and the selector renders nothing (single default).\n */\n readonly views?: NamedViewsCapability\n /**\n * `importExport` — JSON round-trip of the collection's records. CMS-specific;\n * a rail whose records are credential-bearing (users) omits it, so neither the\n * import dialog nor the export action mounts (identities aren't dumped to JSON).\n */\n readonly imports?: ImportCapability\n}\n\n/** EC-595 A2 — the write model of a source (see {@link CollectionViewSource.writes}). */\nexport type CollectionWrites = RecordWrites | DocumentWrites\n\n/**\n * An explicit-save rail: the editor's Save button writes the record. `base` (EC-616) is the\n * record as the editor OPENED it (or as of their last successful save) — a rail that can\n * write per column sends only what differs from it, so a column another writer changed\n * meanwhile is kept; absent for a record being created.\n */\nexport interface RecordWrites {\n readonly kind: 'record'\n save(doc: CmsDocument, base?: CmsDocument): void\n}\n\n/**\n * The revisioned-document write model (EC-595, ratified 2026-10-24): patches at the\n * source, the persister's queue, per-field conflicts, the document subscription.\n */\nexport interface DocumentWrites {\n readonly kind: 'document'\n /**\n * Commit the patches a writer made; resolves once acknowledged (`undefined` in a\n * fixture session). `bases` — REQUIRED, per patch: the revision of the view the writer\n * authored it against (EC-647 — never the session's current one by default; a write\n * that names none is refused).\n */\n commit(\n ref: DocumentRef,\n patches: readonly DocumentPatch[],\n bases: readonly (number | undefined)[],\n ): Promise<CommitOutcome | undefined>\n /** The revision the session's view of a document is at now. */\n revisionOf(ref: DocumentRef): number | undefined\n /**\n * EC-647 — the revision a document value the session SHOWED is at (`undefined` for a\n * value it never showed, or a provisional one): a writer holding the value it displayed\n * holds its revision.\n */\n revisionOfView(view: CmsDocument): number | undefined\n /** Create a document from a whole value (insert-if-absent): duplicate. */\n insert(doc: CmsDocument): void\n /** A fresh document id from the session's injected factory (EC-578). */\n newId(): string\n /** The open per-field conflicts on a document. */\n conflicts(ref: DocumentRef): readonly DocumentConflict[]\n resolveConflict(ref: DocumentRef, conflictId: string, choice: 'theirs' | 'mine'): void\n /** Adopt a row the document subscription pushed (local edits win on their paths until flushed). */\n adoptSnapshot(ref: DocumentRef, record: CmsDocumentRecord | undefined): void\n /** The forced flush's persistence half: await every queued write of the document. */\n flush(ref: DocumentRef): Promise<void>\n /**\n * Write the whole document at `revision` — the revision of the view the snapshot was\n * authored on (EC-647; a document-level key the value-position grammar has no position\n * for — the slot `alias`). A move since is refused, never overwritten.\n */\n replace(doc: CmsDocument, revision: number | undefined): void\n /**\n * EC-595 point 7 — follow ONE document while it is open: every pushed row is adopted\n * under the local edits (the editor rebases), and the presence on it is delivered to\n * `onPresence`. Returns the unsubscribe function.\n */\n subscribe(ref: DocumentRef, onPresence: (presence: readonly PresenceEntry[]) => void): () => void\n /** Thin presence (Stage A): this session is on the document, in `path`'s field (or on no field). */\n reportPresence(ref: DocumentRef, path: ValuePath | undefined): void\n /** This session left the document. */\n clearPresence(ref: DocumentRef): void\n /** This session's presence id (one per tab), so the editor can leave itself out. */\n readonly presenceSessionId: string\n}\n\n/**\n * The capability matrix. Each flag gates a shell region AND the presence of its\n * method group. The **users rail** (EC-240) sets `publish:false`, `versions:false`\n * (credential caution), `create:false` (identity minted by sign-up), and no\n * `liveUrl`/`hierarchy`.\n */\nexport interface CollectionViewCapabilities {\n readonly publish: boolean\n readonly versions: boolean\n readonly locales: boolean\n readonly inlineEdit: boolean\n readonly create: boolean\n /**\n * Duplicate-document action (EC-442, amended same day). Deliberately its own\n * flag, never derived from `create`: the owner call (2026-07-17) is CMS\n * collections ONLY — no primitive rail offers Duplicate for now (identities\n * and uploads aren't copyable content; redirects deferred until requested as\n * a product feature).\n */\n readonly duplicate: boolean\n readonly remove: boolean\n readonly bulk: boolean\n /** The derived live-URL column (published pool × deployment routes). */\n readonly liveUrl: boolean\n /** Parent-self-relation tree mode (hierarchical collections only). */\n readonly hierarchy: boolean\n /** JSON import/export of the collection's records (off for credential rails). */\n readonly importExport: boolean\n /**\n * The rail is administration-scoped (mirrors `ADMIN_ONLY_OPERATIONS`). The\n * nav-permission layer reads this to gate the rail item. Absent ⇒ not admin-only.\n */\n readonly adminOnly?: boolean\n}\n\n/**\n * Principal-based field access (EC-240, AD-18). One tri-state drives BOTH visibility\n * and writability: `edit` (writable), `read` (visible, read-only), `hidden` (not\n * rendered). Default `edit` (default-open). Distinct from content-`hidden(values)`;\n * they compose — a field shows iff *not content-hidden AND access ≠ hidden*, and is\n * editable iff *access = edit AND not otherwise read-only* (published view, `form.readOnly`).\n */\nexport type FieldAccess = 'edit' | 'read' | 'hidden'\n\n/**\n * Resolve a field's effective principal access for a source — its {@link\n * CollectionViewSource.fieldAccess} policy when present, else derived from the\n * boolean `isFieldReadOnly` (default-open). The one place the shell asks \"may this\n * principal edit / see this field?\", so the default-open fallback lives in one spot.\n */\nexport function resolveFieldAccess(\n source: CollectionViewSource,\n field: FieldDef,\n record?: CmsDocument,\n): FieldAccess {\n return source.fieldAccess?.(field, record) ?? (source.isFieldReadOnly(field) ? 'read' : 'edit')\n}\n\n/**\n * Asset display metadata a cell/field renders (thumbnail or labelled badge). EC-587:\n * named apart from core's `ResolvedAsset` (the delivery shape) — this is the studio's\n * label/thumbnail slice; its `alt` is the one reader's (`assetAlt`).\n */\nexport interface AssetDisplay {\n readonly url?: string\n readonly contentType?: string\n readonly title?: string\n readonly filename?: string\n readonly alt?: string\n}\n\n/** `publish` capability. */\nexport interface PublishingCapability {\n /** Published-ness from the version pointer (NOT a row field). */\n isPublished(ref: DocumentRef): boolean\n /**\n * Does this PUBLISHED document's working draft carry unpublished changes\n * (EC-449)? The cheap per-row signal behind the amber \"changed\" `$state` dot —\n * sourced from the MATERIALIZED `hasUnpublishedChanges` record flag (computed\n * once at the write chokepoint), never a per-row snapshot compare. Optional: a\n * source without the signal omits it, and the list derives only\n * published/draft (exactly the pre-EC-449 rendering). Same referentially-stable\n * per-ref accessor shape as {@link isPublished}.\n */\n hasUnpublishedChanges?(ref: DocumentRef): boolean\n publish(ref: DocumentRef): Promise<void>\n unpublish(ref: DocumentRef): Promise<void>\n /**\n * Live URLs for the routable documents, keyed by id — derived from the\n * PUBLISHED pool (never draft rows) so an unpublished slug/parent edit can't\n * leak into a live link (EC-205/EC-216). `null` when the collection is not\n * routable → the live-URL column is hidden. Only present when `capabilities.liveUrl`.\n *\n * EC-628: a {@link ReadState} — the URL map only when the published read answered; a\n * failed read is `error` with its sentence, which the URL column shows in every row\n * (never the \"not published\" dash an empty map would give).\n */\n liveUrls?(): ReadState<ReadonlyMap<string, DocumentUrl>> | null\n}\n\n/**\n * `timestamps` capability (EC-445/EC-447): per-document record timestamps as ISO\n * strings, or `undefined` when a document carries none. The `$updatedAt`/`$publishedAt`\n * pseudo-columns read + sort by these. `updatedAt` is the last-write instant;\n * `publishedAt` (EC-447) is the FIRST-publish instant — set-once on publish, cleared on\n * unpublish, so it is `undefined` for a draft / never-published / currently-unpublished\n * document (the column shows EmDash).\n */\nexport interface DocumentTimestampsCapability {\n updatedAt(ref: DocumentRef): string | undefined\n publishedAt(ref: DocumentRef): string | undefined\n}\n\n/**\n * The reserved pseudo-columns applicable to a source's list (EC-445), derived from\n * its capabilities: `$updatedAt` iff it materializes timestamps, `$state` iff it has a\n * publish lifecycle, `$url` iff it resolves delivery URLs. The one place the list\n * surface + the Display picker agree on which pseudo-columns exist for a source, so\n * the column universe never drifts between where columns render and where they toggle.\n */\nexport function pseudoColumnsForSource(source: CollectionViewSource): string[] {\n return pseudoColumns(source.schema, {\n timestamps: source.timestamps !== undefined,\n publishing: source.publishing !== undefined,\n routable: source.capabilities.liveUrl,\n })\n}\n\n/** `versions` capability. */\nexport interface VersioningCapability {\n restore(ref: DocumentRef, version: number, scope?: RestoreScope): Promise<CmsDocument | null>\n /**\n * The document's recorded version history + live pin. Folds the flush-before-read\n * ordering INTO the loader (the adapter's concern), so every fetch lists an\n * authoritative history regardless of which surface triggered the change (EC-224).\n */\n load(ref: DocumentRef): Promise<DocumentVersionsView>\n}\n\n/** `inlineEdit` capability: the list's single-command optimistic cell write (EC-168). */\nexport interface InlineEditCapability {\n commitField(input: CellCommitInput): Promise<CellCommitOutcome>\n}\n\n/** A named lens the header selector offers — id + display name only (the header never needs its state). */\nexport interface NamedView {\n readonly id: string\n /** Display name; a {@link LocalizedString} (EC-343), resolved at the render site like `form.label`. */\n readonly name: LocalizedString\n}\n\n/** `importExport` capability: validate + fold external JSON records into the collection (EC-079). */\nexport interface ImportCapability {\n importDocuments(items: unknown[]): ImportReport\n}\n\n/**\n * `views` capability: config-as-code named lenses (EC-246b). The header selector\n * only *picks* a lens — it never creates/edits/deletes one (shared views are code).\n */\nexport interface NamedViewsCapability {\n /** The built-in default + config-declared named views. */\n list(): readonly NamedView[]\n /** The currently-selected view id. */\n activeId(): string\n /** Switch views (resets the working table state to the view's baseline). */\n setActive(id: string): void\n}\n\nexport type { CellCommitInput, CellCommitOutcome, ImportReport }\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContentClient, createContentContext, queryError, validateLimit, validateSort, validateWhere, } from '@elytracms/core/content';
|
|
2
2
|
import { documentKey, localeSchema, parseLocaleConfig, perspectiveKey, resolveDocumentTitle, valuesInLocale, } from '@elytracms/core/cms-core';
|
|
3
|
+
import { assetMetaLens } from '@elytracms/core/persistence';
|
|
3
4
|
import { listingRequestOf } from '@elytracms/core/runtime-renderer';
|
|
4
5
|
import { getStudioLocale, getStudioLocaleConfig } from '../locale/locale-store.js';
|
|
5
6
|
/**
|
|
@@ -247,6 +248,10 @@ function clientFor(locale, perspective = 'published') {
|
|
|
247
248
|
locale,
|
|
248
249
|
perspective,
|
|
249
250
|
locales,
|
|
251
|
+
// EC-659: the session's asset collection is the lens over stored asset metadata — the
|
|
252
|
+
// preview applies a translation exactly where delivery does. The session's collections
|
|
253
|
+
// change only with the session, which clears this cache.
|
|
254
|
+
assetMetaLens: assetMetaLens(activeCollections()),
|
|
250
255
|
}),
|
|
251
256
|
// EC-291: the routes a rich-text link resolves against (config-sourced) — the
|
|
252
257
|
// studio-live half of the host link bake.
|