@murumets-ee/content 0.1.4 → 0.2.0
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/dist/block-diff-H1AttKiz.mjs +2 -0
- package/dist/block-diff-H1AttKiz.mjs.map +1 -0
- package/dist/blocks/index.d.mts +197 -0
- package/dist/blocks/index.d.mts.map +1 -0
- package/dist/blocks/index.mjs +2 -0
- package/dist/blocks/index.mjs.map +1 -0
- package/dist/client.d.mts +213 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +2 -0
- package/dist/client.mjs.map +1 -0
- package/dist/define-block-D-7OpIn5.mjs +2 -0
- package/dist/define-block-D-7OpIn5.mjs.map +1 -0
- package/dist/drafts-BYyRdmiT.mjs +2 -0
- package/dist/drafts-BYyRdmiT.mjs.map +1 -0
- package/dist/index.d.mts +71 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/locale-status-CGttT38v.mjs +2 -0
- package/dist/locale-status-CGttT38v.mjs.map +1 -0
- package/dist/lock-service.d.mts +54 -0
- package/dist/lock-service.d.mts.map +1 -0
- package/dist/lock-service.mjs +2 -0
- package/dist/lock-service.mjs.map +1 -0
- package/dist/locks-CNxQJieo.mjs +2 -0
- package/dist/locks-CNxQJieo.mjs.map +1 -0
- package/dist/plugin.d.mts +15 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +2 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/query-client.d.mts +60 -0
- package/dist/query-client.d.mts.map +1 -0
- package/dist/query-client.mjs +2 -0
- package/dist/query-client.mjs.map +1 -0
- package/dist/types-nXbE5Ufa.d.mts +43 -0
- package/dist/types-nXbE5Ufa.d.mts.map +1 -0
- package/dist/types-wLHyjcWf.d.mts +95 -0
- package/dist/types-wLHyjcWf.d.mts.map +1 -0
- package/dist/versions-cotph2VG.mjs +2 -0
- package/dist/versions-cotph2VG.mjs.map +1 -0
- package/package.json +20 -20
- package/dist/blocks/index.d.ts +0 -187
- package/dist/blocks/index.js +0 -1
- package/dist/chunk-BVMZMEPV.js +0 -1
- package/dist/chunk-CULYIGZI.js +0 -1
- package/dist/client.d.ts +0 -215
- package/dist/client.js +0 -1
- package/dist/drafts-2ZRAHAUK.js +0 -1
- package/dist/index.d.ts +0 -142
- package/dist/index.js +0 -1
- package/dist/locale-status-B7B3WFXF.js +0 -1
- package/dist/lock-service.d.ts +0 -61
- package/dist/lock-service.js +0 -1
- package/dist/locks-AXFCTV7F.js +0 -1
- package/dist/plugin.d.ts +0 -33
- package/dist/plugin.js +0 -1
- package/dist/query-client.d.ts +0 -67
- package/dist/query-client.js +0 -1
- package/dist/types-BYeiE1ie.d.ts +0 -99
- package/dist/types-Cr0ifLn_.d.ts +0 -41
- package/dist/versions-4ICOJIK2.js +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{field as e}from"@murumets-ee/entity";const t={maxPerDoc:50,autosave:!1};function n(n){let r={...t,...n};return{name:`versionable`,fields:{_version:e.number({required:!0,default:1,integer:!0}),_versionedAt:e.date()},hooks:{beforeCreate:async e=>(e._version=1,e._versionedAt=new Date,e),beforeUpdate:async(e,t)=>(t._versionedAt=new Date,t)},_versionableOptions:r}}function r(e){return e?e.find(e=>e.name===`versionable`)?._versionableOptions??null:null}function i(e){return e.match(/\S+|\s+/g)??[]}function a(e,t){if(e===t)return e?[{type:`equal`,value:e}]:[];if(!e)return[{type:`add`,value:t}];if(!t)return[{type:`remove`,value:e}];let n=i(e),r=i(t),a=n.length,o=r.length,s=Array.from({length:a+1},()=>Array(o+1).fill(0));for(let e=1;e<=a;e++)for(let t=1;t<=o;t++)n[e-1]===r[t-1]?s[e][t]=s[e-1][t-1]+1:s[e][t]=Math.max(s[e-1][t],s[e][t-1]);let c=[],l=a,u=o,d=[];for(;l>0||u>0;)l>0&&u>0&&n[l-1]===r[u-1]?(d.push({type:`equal`,value:n[l-1]}),l--,u--):u>0&&(l===0||s[l][u-1]>=s[l-1][u])?(d.push({type:`add`,value:r[u-1]}),u--):(d.push({type:`remove`,value:n[l-1]}),l--);d.reverse();for(let e of d){let t=c[c.length-1];t&&t.type===e.type?t.value+=e.value:c.push({...e})}return c}function o(e){return e.replace(/<[^>]*>/g,` `).replace(/\s+/g,` `).trim()}function s(e){return e==null?``:e instanceof Date?e.toISOString():typeof e==`object`?JSON.stringify(e):String(e)}function c(e,t,n,r){if(JSON.stringify(t)===JSON.stringify(n))return null;switch(r?.type??u(t,n)){case`text`:case`slug`:return{field:e,type:`text`,from:t,to:n,segments:a(s(t),s(n))};case`richtext`:return{field:e,type:`richtext`,from:t,to:n,segments:a(o(s(t)),o(s(n)))};case`number`:return{field:e,type:`number`,from:t,to:n};case`boolean`:return{field:e,type:`boolean`,from:t,to:n};case`date`:return{field:e,type:`date`,from:t,to:n};case`select`:return{field:e,type:`select`,from:t,to:n};case`media`:return{field:e,type:`media`,from:t,to:n};case`json`:return{field:e,type:`json`,from:t,to:n};case`blocks`:return{field:e,type:`blocks`,from:t,to:n};default:return{field:e,type:`unknown`,from:t,to:n}}}function l(e,t,n){let r=new Set([...Object.keys(e),...Object.keys(t)]),i=[];for(let a of r){if(a===`id`||a===`createdAt`||a===`updatedAt`)continue;let r=c(a,e[a],t[a],n?.[a]);r&&i.push(r)}return i}function u(e,t){let n=e??t;return typeof n==`number`?`number`:typeof n==`boolean`?`boolean`:n instanceof Date?`date`:typeof n==`string`?/^\d{4}-\d{2}-\d{2}/.test(n)?`date`:`text`:Array.isArray(n)?n.length>0&&typeof n[0]==`object`&&n[0]!==null&&`_block`in n[0]?`blocks`:`json`:typeof n==`object`?`json`:`unknown`}function d(e,t){if(typeof e==`string`||typeof t==`string`)return a(s(e),s(t))}function f(e){return typeof e==`object`&&!!e&&`_block`in e&&`_id`in e&&typeof e._block==`string`&&typeof e._id==`string`}function p(e,t){let n=new Set([...Object.keys(e),...Object.keys(t)]),r=[];for(let i of n){if(i===`_block`||i===`_id`)continue;let n=e[i],a=t[i];JSON.stringify(n)!==JSON.stringify(a)&&r.push({field:i,from:n,to:a,segments:d(n,a)})}return r}function m(e,t){let n=e.filter(f),r=t.filter(f),i=new Map,a=new Map;for(let e=0;e<n.length;e++)i.set(n[e]._id,{block:n[e],index:e});for(let e=0;e<r.length;e++)a.set(r[e]._id,{block:r[e],index:e});let o=[],s=new Set;for(let[e,{block:t,index:n}]of a){s.add(e);let r=i.get(e);if(!r){o.push({blockId:e,blockType:t._block,status:`added`,toIndex:n});continue}let a=r.block,c=r.index,l=p(a,t),u=c!==n;l.length===0&&!u?o.push({blockId:e,blockType:t._block,status:`unchanged`,fromIndex:c,toIndex:n}):l.length>0?o.push({blockId:e,blockType:t._block,status:`changed`,fromIndex:c,toIndex:n,propDiffs:l}):o.push({blockId:e,blockType:t._block,status:`moved`,fromIndex:c,toIndex:n})}for(let[e,{block:t,index:n}]of i)s.has(e)||o.push({blockId:e,blockType:t._block,status:`removed`,fromIndex:n});return o}export{a,d as i,c as n,r as o,l as r,n as s,m as t};
|
|
2
|
+
//# sourceMappingURL=block-diff-H1AttKiz.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-diff-H1AttKiz.mjs","names":[],"sources":["../src/behaviors/versionable.ts","../src/diff/text-diff.ts","../src/diff/field-diff.ts","../src/diff/block-diff.ts"],"sourcesContent":["/**\n * Versionable behavior — full version history with snapshots.\n *\n * Extends the concept of revisionable() (which only tracks a counter)\n * with actual version snapshots stored in {entity}_versions table.\n *\n * The behavior itself adds fields + hooks for version tracking.\n * Actual snapshot persistence happens in ContentClient (which has DB access).\n *\n * Options:\n * - maxPerDoc: Maximum versions kept per document (default: 50)\n * - autosave: Enable smart autosave (default: false)\n */\n\nimport type { Behavior, DateField, NumberField } from '@murumets-ee/entity'\n\nimport { field } from '@murumets-ee/entity'\nimport type { VersionableOptions } from '../types.js'\n\nexport type VersionableFields = {\n _version: NumberField & { required: true }\n _versionedAt: DateField\n}\n\nconst DEFAULT_OPTIONS: Required<VersionableOptions> = {\n maxPerDoc: 50,\n autosave: false,\n}\n\nexport function versionable(options?: VersionableOptions): Behavior<VersionableFields> {\n const opts = { ...DEFAULT_OPTIONS, ...options }\n\n // Attach options to the behavior for ContentClient to read\n const behavior: Behavior<VersionableFields> & {\n _versionableOptions: Required<VersionableOptions>\n } = {\n name: 'versionable',\n fields: {\n _version: field.number({ required: true, default: 1, integer: true }),\n _versionedAt: field.date(),\n },\n hooks: {\n beforeCreate: async (data) => {\n data._version = 1\n data._versionedAt = new Date()\n return data\n },\n beforeUpdate: async (_id, data) => {\n // Only update _versionedAt here. The _version increment is handled by\n // createVersionSnapshot which reads the current version from the DB.\n // The beforeUpdate hook only receives partial data (the PATCH payload),\n // so it can't reliably increment _version without the current value.\n data._versionedAt = new Date()\n return data\n },\n },\n _versionableOptions: opts,\n }\n\n return behavior as Behavior<VersionableFields>\n}\n\n/**\n * Extract versionable options from an entity's behaviors\n */\nexport function getVersionableOptions(behaviors?: Behavior[]): Required<VersionableOptions> | null {\n if (!behaviors) return null\n const vBehavior = behaviors.find((b) => b.name === 'versionable') as\n | (Behavior & { _versionableOptions?: Required<VersionableOptions> })\n | undefined\n return vBehavior?._versionableOptions ?? null\n}\n","/**\n * Word-level text diff using a simplified Myers algorithm.\n *\n * Splits text into words (preserving whitespace), computes the longest common\n * subsequence, and returns an array of diff segments.\n */\n\nimport type { DiffSegment } from './types.js'\n\n/**\n * Split text into tokens — words and whitespace runs — so diffs are\n * human-readable (\"Changed *this* word\") rather than character-level.\n */\nfunction tokenize(text: string): string[] {\n return text.match(/\\S+|\\s+/g) ?? []\n}\n\n/**\n * Compute word-level diff between two strings.\n *\n * Uses a simple LCS (dynamic programming) approach which is fine for\n * the text sizes we deal with (entity field values, not source code).\n */\nexport function diffText(from: string, to: string): DiffSegment[] {\n if (from === to) {\n return from ? [{ type: 'equal', value: from }] : []\n }\n if (!from) {\n return [{ type: 'add', value: to }]\n }\n if (!to) {\n return [{ type: 'remove', value: from }]\n }\n\n const fromTokens = tokenize(from)\n const toTokens = tokenize(to)\n\n // Build LCS table\n const m = fromTokens.length\n const n = toTokens.length\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (fromTokens[i - 1] === toTokens[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1] + 1\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])\n }\n }\n }\n\n // Backtrack to build diff segments\n const segments: DiffSegment[] = []\n let i = m\n let j = n\n\n // Collect in reverse, then flip\n const reversed: DiffSegment[] = []\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && fromTokens[i - 1] === toTokens[j - 1]) {\n reversed.push({ type: 'equal', value: fromTokens[i - 1] })\n i--\n j--\n } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {\n reversed.push({ type: 'add', value: toTokens[j - 1] })\n j--\n } else {\n reversed.push({ type: 'remove', value: fromTokens[i - 1] })\n i--\n }\n }\n\n reversed.reverse()\n\n // Merge consecutive segments of the same type\n for (const seg of reversed) {\n const last = segments[segments.length - 1]\n if (last && last.type === seg.type) {\n last.value += seg.value\n } else {\n segments.push({ ...seg })\n }\n }\n\n return segments\n}\n","/**\n * Field-level diff — dispatches to the appropriate diff strategy per field type.\n */\n\nimport type { FieldConfig } from '@murumets-ee/entity'\nimport { diffText } from './text-diff.js'\nimport type { DiffSegment, FieldDiff } from './types.js'\n\n/** Strip HTML tags for diffing richtext content as plain text. */\nfunction stripHtml(html: string): string {\n return html\n .replace(/<[^>]*>/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/** Stringify a value for display (dates, objects, etc.). */\nfunction stringify(value: unknown): string {\n if (value === null || value === undefined) return ''\n if (value instanceof Date) return value.toISOString()\n if (typeof value === 'object') return JSON.stringify(value)\n return String(value)\n}\n\n/**\n * Compute diff for a single field, using the field's type to determine\n * the best diff strategy.\n */\nexport function diffField(\n fieldName: string,\n from: unknown,\n to: unknown,\n fieldConfig?: FieldConfig,\n): FieldDiff | null {\n // No change\n if (JSON.stringify(from) === JSON.stringify(to)) return null\n\n const type = fieldConfig?.type ?? inferType(from, to)\n\n switch (type) {\n case 'text':\n case 'slug': {\n const segments = diffText(stringify(from), stringify(to))\n return { field: fieldName, type: 'text', from, to, segments }\n }\n\n case 'richtext': {\n // Diff on stripped HTML so users see word changes, not tag noise\n const segments = diffText(stripHtml(stringify(from)), stripHtml(stringify(to)))\n return { field: fieldName, type: 'richtext', from, to, segments }\n }\n\n case 'number':\n return { field: fieldName, type: 'number', from, to }\n\n case 'boolean':\n return { field: fieldName, type: 'boolean', from, to }\n\n case 'date':\n return { field: fieldName, type: 'date', from, to }\n\n case 'select':\n return { field: fieldName, type: 'select', from, to }\n\n case 'media':\n return { field: fieldName, type: 'media', from, to }\n\n case 'json':\n return { field: fieldName, type: 'json', from, to }\n\n case 'blocks':\n // Blocks are handled separately by block-diff.ts — just mark the field\n return { field: fieldName, type: 'blocks', from, to }\n\n default:\n return { field: fieldName, type: 'unknown', from, to }\n }\n}\n\n/**\n * Diff all fields between two version snapshots.\n * Pass fieldConfigs to get type-aware diffs; without them, types are inferred.\n */\nexport function diffFields(\n from: Record<string, unknown>,\n to: Record<string, unknown>,\n fieldConfigs?: Record<string, FieldConfig>,\n): FieldDiff[] {\n const allKeys = new Set([...Object.keys(from), ...Object.keys(to)])\n const diffs: FieldDiff[] = []\n\n for (const key of allKeys) {\n // Skip internal/auto-generated fields\n if (key === 'id' || key === 'createdAt' || key === 'updatedAt') continue\n\n const diff = diffField(key, from[key], to[key], fieldConfigs?.[key])\n if (diff) diffs.push(diff)\n }\n\n return diffs\n}\n\n/** Best-effort type inference when no FieldConfig is available. */\nfunction inferType(from: unknown, to: unknown): string {\n const val = from ?? to\n if (typeof val === 'number') return 'number'\n if (typeof val === 'boolean') return 'boolean'\n if (val instanceof Date) return 'date'\n if (typeof val === 'string') {\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(val)) return 'date'\n return 'text'\n }\n if (Array.isArray(val)) {\n // Check if it looks like a blocks array\n if (val.length > 0 && typeof val[0] === 'object' && val[0] !== null && '_block' in val[0]) {\n return 'blocks'\n }\n return 'json'\n }\n if (typeof val === 'object') return 'json'\n return 'unknown'\n}\n\n/** Diff two string values and return segments (used by block-diff for string props). */\nexport function diffStringValues(from: unknown, to: unknown): DiffSegment[] | undefined {\n if (typeof from === 'string' || typeof to === 'string') {\n return diffText(stringify(from), stringify(to))\n }\n return undefined\n}\n","/**\n * Structural diff for Puck block arrays.\n *\n * Blocks are identified by `_id`. The algorithm detects:\n * - Added blocks (new _id in target)\n * - Removed blocks (missing _id in target)\n * - Moved blocks (same _id, different position)\n * - Changed blocks (same _id, different prop values)\n * - Unchanged blocks\n */\n\nimport { diffStringValues } from './field-diff.js'\nimport type { BlockDiffEntry, PropDiff } from './types.js'\n\ninterface Block {\n _block: string\n _id: string\n [key: string]: unknown\n}\n\nfunction isBlock(val: unknown): val is Block {\n return (\n typeof val === 'object' &&\n val !== null &&\n '_block' in val &&\n '_id' in val &&\n typeof (val as Block)._block === 'string' &&\n typeof (val as Block)._id === 'string'\n )\n}\n\n/**\n * Diff two prop objects within a single block, returning per-prop diffs.\n */\nfunction diffProps(\n fromProps: Record<string, unknown>,\n toProps: Record<string, unknown>,\n): PropDiff[] {\n const allKeys = new Set([...Object.keys(fromProps), ...Object.keys(toProps)])\n const diffs: PropDiff[] = []\n\n for (const key of allKeys) {\n // Skip block metadata\n if (key === '_block' || key === '_id') continue\n\n const fromVal = fromProps[key]\n const toVal = toProps[key]\n\n if (JSON.stringify(fromVal) !== JSON.stringify(toVal)) {\n diffs.push({\n field: key,\n from: fromVal,\n to: toVal,\n segments: diffStringValues(fromVal, toVal),\n })\n }\n }\n\n return diffs\n}\n\n/**\n * Compute structural diff between two block arrays.\n *\n * Each block is identified by its `_id` field. Position changes,\n * additions, removals, and prop-level changes are all detected.\n */\nexport function diffBlocks(fromBlocks: unknown[], toBlocks: unknown[]): BlockDiffEntry[] {\n const from = fromBlocks.filter(isBlock)\n const to = toBlocks.filter(isBlock)\n\n const fromMap = new Map<string, { block: Block; index: number }>()\n const toMap = new Map<string, { block: Block; index: number }>()\n\n for (let i = 0; i < from.length; i++) {\n fromMap.set(from[i]._id, { block: from[i], index: i })\n }\n for (let i = 0; i < to.length; i++) {\n toMap.set(to[i]._id, { block: to[i], index: i })\n }\n\n const entries: BlockDiffEntry[] = []\n const processedIds = new Set<string>()\n\n // Walk the \"to\" array to preserve target order\n for (const [id, { block: toBlock, index: toIndex }] of toMap) {\n processedIds.add(id)\n const fromEntry = fromMap.get(id)\n\n if (!fromEntry) {\n // Added\n entries.push({\n blockId: id,\n blockType: toBlock._block,\n status: 'added',\n toIndex,\n })\n continue\n }\n\n const fromBlock = fromEntry.block\n const fromIndex = fromEntry.index\n const propDiffs = diffProps(fromBlock, toBlock)\n const moved = fromIndex !== toIndex\n\n if (propDiffs.length === 0 && !moved) {\n entries.push({\n blockId: id,\n blockType: toBlock._block,\n status: 'unchanged',\n fromIndex,\n toIndex,\n })\n } else if (propDiffs.length > 0) {\n entries.push({\n blockId: id,\n blockType: toBlock._block,\n status: 'changed',\n fromIndex,\n toIndex,\n propDiffs,\n })\n } else {\n entries.push({\n blockId: id,\n blockType: toBlock._block,\n status: 'moved',\n fromIndex,\n toIndex,\n })\n }\n }\n\n // Removed blocks (in \"from\" but not in \"to\")\n for (const [id, { block, index }] of fromMap) {\n if (!processedIds.has(id)) {\n entries.push({\n blockId: id,\n blockType: block._block,\n status: 'removed',\n fromIndex: index,\n })\n }\n }\n\n return entries\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { t as BlockDefinition } from "../types-wLHyjcWf.mjs";
|
|
2
|
+
import * as _$_murumets_ee_entity0 from "@murumets-ee/entity";
|
|
3
|
+
|
|
4
|
+
//#region src/blocks/code.d.ts
|
|
5
|
+
declare const CodeBlock: BlockDefinition<{
|
|
6
|
+
readonly code: _$_murumets_ee_entity0.TextField & {
|
|
7
|
+
readonly required: true;
|
|
8
|
+
};
|
|
9
|
+
readonly language: _$_murumets_ee_entity0.SelectField & {
|
|
10
|
+
options: readonly ["javascript", "typescript", "python", "html", "css", "json", "bash", "sql", "other"];
|
|
11
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
12
|
+
}>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/blocks/cta.d.ts
|
|
15
|
+
declare const CTABlock: BlockDefinition<{
|
|
16
|
+
readonly heading: _$_murumets_ee_entity0.TextField & {
|
|
17
|
+
readonly required: true;
|
|
18
|
+
readonly translatable: true;
|
|
19
|
+
};
|
|
20
|
+
readonly description: _$_murumets_ee_entity0.TextField & {
|
|
21
|
+
readonly translatable: true;
|
|
22
|
+
};
|
|
23
|
+
readonly buttonText: _$_murumets_ee_entity0.TextField & {
|
|
24
|
+
readonly required: true;
|
|
25
|
+
readonly translatable: true;
|
|
26
|
+
};
|
|
27
|
+
readonly buttonLink: _$_murumets_ee_entity0.TextField & {
|
|
28
|
+
readonly required: true;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/blocks/gallery.d.ts
|
|
33
|
+
declare const GalleryBlock: BlockDefinition<{
|
|
34
|
+
readonly images: _$_murumets_ee_entity0.ReferenceField & {
|
|
35
|
+
cardinality: "many";
|
|
36
|
+
} & Partial<Omit<_$_murumets_ee_entity0.ReferenceField, "cardinality" | "entity">>;
|
|
37
|
+
readonly columns: _$_murumets_ee_entity0.SelectField & {
|
|
38
|
+
options: readonly ["2", "3", "4"];
|
|
39
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
40
|
+
}>;
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/blocks/hero.d.ts
|
|
43
|
+
declare const HeroBlock: BlockDefinition<{
|
|
44
|
+
readonly heading: _$_murumets_ee_entity0.TextField & {
|
|
45
|
+
readonly required: true;
|
|
46
|
+
readonly translatable: true;
|
|
47
|
+
};
|
|
48
|
+
readonly subheading: _$_murumets_ee_entity0.TextField & {
|
|
49
|
+
readonly translatable: true;
|
|
50
|
+
};
|
|
51
|
+
readonly background: _$_murumets_ee_entity0.MediaField & {
|
|
52
|
+
readonly accept: ["image/*"];
|
|
53
|
+
};
|
|
54
|
+
readonly alignment: _$_murumets_ee_entity0.SelectField & {
|
|
55
|
+
options: readonly ["left", "center", "right"];
|
|
56
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
57
|
+
}>;
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/blocks/image.d.ts
|
|
60
|
+
declare const ImageBlock: BlockDefinition<{
|
|
61
|
+
readonly image: _$_murumets_ee_entity0.MediaField & {
|
|
62
|
+
readonly accept: ["image/*"];
|
|
63
|
+
readonly required: true;
|
|
64
|
+
};
|
|
65
|
+
readonly alt: _$_murumets_ee_entity0.TextField & {
|
|
66
|
+
readonly translatable: true;
|
|
67
|
+
};
|
|
68
|
+
readonly caption: _$_murumets_ee_entity0.TextField & {
|
|
69
|
+
readonly translatable: true;
|
|
70
|
+
};
|
|
71
|
+
}>;
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/blocks/quote.d.ts
|
|
74
|
+
declare const QuoteBlock: BlockDefinition<{
|
|
75
|
+
readonly quote: _$_murumets_ee_entity0.TextField & {
|
|
76
|
+
readonly required: true;
|
|
77
|
+
readonly translatable: true;
|
|
78
|
+
};
|
|
79
|
+
readonly attribution: _$_murumets_ee_entity0.TextField & {
|
|
80
|
+
readonly translatable: true;
|
|
81
|
+
};
|
|
82
|
+
}>;
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/blocks/richtext.d.ts
|
|
85
|
+
declare const RichTextBlock: BlockDefinition<{
|
|
86
|
+
readonly content: _$_murumets_ee_entity0.RichTextField & {
|
|
87
|
+
readonly translatable: true;
|
|
88
|
+
};
|
|
89
|
+
}>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/blocks/video.d.ts
|
|
92
|
+
declare const VideoBlock: BlockDefinition<{
|
|
93
|
+
readonly url: _$_murumets_ee_entity0.TextField & {
|
|
94
|
+
readonly required: true;
|
|
95
|
+
};
|
|
96
|
+
readonly poster: _$_murumets_ee_entity0.MediaField & {
|
|
97
|
+
readonly accept: ["image/*"];
|
|
98
|
+
};
|
|
99
|
+
readonly caption: _$_murumets_ee_entity0.TextField & {
|
|
100
|
+
readonly translatable: true;
|
|
101
|
+
};
|
|
102
|
+
}>;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/blocks/index.d.ts
|
|
105
|
+
/**
|
|
106
|
+
* All common blocks shipped with the toolkit.
|
|
107
|
+
* Use as-is or pick individual blocks from the named exports.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* import { commonBlocks } from '@murumets-ee/content/blocks'
|
|
111
|
+
* const Page = defineEntity({
|
|
112
|
+
* name: 'page',
|
|
113
|
+
* fields: {
|
|
114
|
+
* layout: field.blocks({ blocks: [...commonBlocks] }),
|
|
115
|
+
* },
|
|
116
|
+
* })
|
|
117
|
+
*/
|
|
118
|
+
declare const commonBlocks: readonly [BlockDefinition<{
|
|
119
|
+
readonly content: _$_murumets_ee_entity0.RichTextField & {
|
|
120
|
+
readonly translatable: true;
|
|
121
|
+
};
|
|
122
|
+
}>, BlockDefinition<{
|
|
123
|
+
readonly image: _$_murumets_ee_entity0.MediaField & {
|
|
124
|
+
readonly accept: ["image/*"];
|
|
125
|
+
readonly required: true;
|
|
126
|
+
};
|
|
127
|
+
readonly alt: _$_murumets_ee_entity0.TextField & {
|
|
128
|
+
readonly translatable: true;
|
|
129
|
+
};
|
|
130
|
+
readonly caption: _$_murumets_ee_entity0.TextField & {
|
|
131
|
+
readonly translatable: true;
|
|
132
|
+
};
|
|
133
|
+
}>, BlockDefinition<{
|
|
134
|
+
readonly heading: _$_murumets_ee_entity0.TextField & {
|
|
135
|
+
readonly required: true;
|
|
136
|
+
readonly translatable: true;
|
|
137
|
+
};
|
|
138
|
+
readonly subheading: _$_murumets_ee_entity0.TextField & {
|
|
139
|
+
readonly translatable: true;
|
|
140
|
+
};
|
|
141
|
+
readonly background: _$_murumets_ee_entity0.MediaField & {
|
|
142
|
+
readonly accept: ["image/*"];
|
|
143
|
+
};
|
|
144
|
+
readonly alignment: _$_murumets_ee_entity0.SelectField & {
|
|
145
|
+
options: readonly ["left", "center", "right"];
|
|
146
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
147
|
+
}>, BlockDefinition<{
|
|
148
|
+
readonly images: _$_murumets_ee_entity0.ReferenceField & {
|
|
149
|
+
cardinality: "many";
|
|
150
|
+
} & Partial<Omit<_$_murumets_ee_entity0.ReferenceField, "cardinality" | "entity">>;
|
|
151
|
+
readonly columns: _$_murumets_ee_entity0.SelectField & {
|
|
152
|
+
options: readonly ["2", "3", "4"];
|
|
153
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
154
|
+
}>, BlockDefinition<{
|
|
155
|
+
readonly heading: _$_murumets_ee_entity0.TextField & {
|
|
156
|
+
readonly required: true;
|
|
157
|
+
readonly translatable: true;
|
|
158
|
+
};
|
|
159
|
+
readonly description: _$_murumets_ee_entity0.TextField & {
|
|
160
|
+
readonly translatable: true;
|
|
161
|
+
};
|
|
162
|
+
readonly buttonText: _$_murumets_ee_entity0.TextField & {
|
|
163
|
+
readonly required: true;
|
|
164
|
+
readonly translatable: true;
|
|
165
|
+
};
|
|
166
|
+
readonly buttonLink: _$_murumets_ee_entity0.TextField & {
|
|
167
|
+
readonly required: true;
|
|
168
|
+
};
|
|
169
|
+
}>, BlockDefinition<{
|
|
170
|
+
readonly url: _$_murumets_ee_entity0.TextField & {
|
|
171
|
+
readonly required: true;
|
|
172
|
+
};
|
|
173
|
+
readonly poster: _$_murumets_ee_entity0.MediaField & {
|
|
174
|
+
readonly accept: ["image/*"];
|
|
175
|
+
};
|
|
176
|
+
readonly caption: _$_murumets_ee_entity0.TextField & {
|
|
177
|
+
readonly translatable: true;
|
|
178
|
+
};
|
|
179
|
+
}>, BlockDefinition<{
|
|
180
|
+
readonly quote: _$_murumets_ee_entity0.TextField & {
|
|
181
|
+
readonly required: true;
|
|
182
|
+
readonly translatable: true;
|
|
183
|
+
};
|
|
184
|
+
readonly attribution: _$_murumets_ee_entity0.TextField & {
|
|
185
|
+
readonly translatable: true;
|
|
186
|
+
};
|
|
187
|
+
}>, BlockDefinition<{
|
|
188
|
+
readonly code: _$_murumets_ee_entity0.TextField & {
|
|
189
|
+
readonly required: true;
|
|
190
|
+
};
|
|
191
|
+
readonly language: _$_murumets_ee_entity0.SelectField & {
|
|
192
|
+
options: readonly ["javascript", "typescript", "python", "html", "css", "json", "bash", "sql", "other"];
|
|
193
|
+
} & Omit<Partial<_$_murumets_ee_entity0.SelectField>, "options">;
|
|
194
|
+
}>];
|
|
195
|
+
//#endregion
|
|
196
|
+
export { CTABlock, CodeBlock, GalleryBlock, HeroBlock, ImageBlock, QuoteBlock, RichTextBlock, VideoBlock, commonBlocks };
|
|
197
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/blocks/code.ts","../../src/blocks/cta.ts","../../src/blocks/gallery.ts","../../src/blocks/hero.ts","../../src/blocks/image.ts","../../src/blocks/quote.ts","../../src/blocks/richtext.ts","../../src/blocks/video.ts","../../src/blocks/index.ts"],"mappings":";;;;cAGa,SAAA;iBAmBX,sBAAA,CAAA,SAAA;IAAA;;;;;;;;cCnBW,QAAA;oBASX,sBAAA,CAAA,SAAA;IAAA;;;;;;;;;;;;;;;;cCTW,YAAA;mBAOX,sBAAA,CAAA,cAAA;;;;;;;;;cCPW,SAAA;oBASX,sBAAA,CAAA,SAAA;IAAA;;;;;;;;;;;;;;;cCTW,UAAA;kBAQX,sBAAA,CAAA,UAAA;IAAA;;;;;;;;;;;;cCRW,UAAA;kBAOX,sBAAA,CAAA,SAAA;IAAA;;;;;;;;;cCPW,aAAA,EAMX,eAAA;EAAA,kBAAA,sBAAA,CAAA,aAAA;IAAA;;;;;cCNW,UAAA;gBAQX,sBAAA,CAAA,SAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;cCoBW,YAAA;oBASH,sBAAA,CAAA,aAAA;IAAA;;;kBATe,sBAAA,CAAA,UAAA;IAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"../define-block-D-7OpIn5.mjs";import{field as t}from"@murumets-ee/entity";const n=e({slug:`code`,label:`Code`,fields:{code:t.text({required:!0}),language:t.select({options:[`javascript`,`typescript`,`python`,`html`,`css`,`json`,`bash`,`sql`,`other`]})}}),r=e({slug:`cta`,label:`Call to Action`,fields:{heading:t.text({required:!0,translatable:!0}),description:t.text({translatable:!0}),buttonText:t.text({required:!0,translatable:!0}),buttonLink:t.text({required:!0})}}),i=e({slug:`gallery`,label:`Gallery`,fields:{images:t.reference({entity:`media`,cardinality:`many`}),columns:t.select({options:[`2`,`3`,`4`]})}}),a=e({slug:`hero`,label:`Hero Section`,fields:{heading:t.text({required:!0,translatable:!0}),subheading:t.text({translatable:!0}),background:t.media({accept:[`image/*`]}),alignment:t.select({options:[`left`,`center`,`right`]})}}),o=e({slug:`image`,label:`Image`,fields:{image:t.media({accept:[`image/*`],required:!0}),alt:t.text({translatable:!0}),caption:t.text({translatable:!0})}}),s=e({slug:`quote`,label:`Quote`,fields:{quote:t.text({required:!0,translatable:!0}),attribution:t.text({translatable:!0})}}),c=e({slug:`richtext`,label:`Rich Text`,fields:{content:t.richtext({translatable:!0})}}),l=e({slug:`video`,label:`Video`,fields:{url:t.text({required:!0}),poster:t.media({accept:[`image/*`]}),caption:t.text({translatable:!0})}}),u=[c,o,a,i,r,l,s,n];export{r as CTABlock,n as CodeBlock,i as GalleryBlock,a as HeroBlock,o as ImageBlock,s as QuoteBlock,c as RichTextBlock,l as VideoBlock,u as commonBlocks};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/blocks/code.ts","../../src/blocks/cta.ts","../../src/blocks/gallery.ts","../../src/blocks/hero.ts","../../src/blocks/image.ts","../../src/blocks/quote.ts","../../src/blocks/richtext.ts","../../src/blocks/video.ts","../../src/blocks/index.ts"],"sourcesContent":["import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const CodeBlock = defineBlock({\n slug: 'code',\n label: 'Code',\n fields: {\n code: field.text({ required: true }),\n language: field.select({\n options: [\n 'javascript',\n 'typescript',\n 'python',\n 'html',\n 'css',\n 'json',\n 'bash',\n 'sql',\n 'other',\n ],\n }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const CTABlock = defineBlock({\n slug: 'cta',\n label: 'Call to Action',\n fields: {\n heading: field.text({ required: true, translatable: true }),\n description: field.text({ translatable: true }),\n buttonText: field.text({ required: true, translatable: true }),\n buttonLink: field.text({ required: true }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const GalleryBlock = defineBlock({\n slug: 'gallery',\n label: 'Gallery',\n fields: {\n images: field.reference({ entity: 'media', cardinality: 'many' }),\n columns: field.select({ options: ['2', '3', '4'] }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const HeroBlock = defineBlock({\n slug: 'hero',\n label: 'Hero Section',\n fields: {\n heading: field.text({ required: true, translatable: true }),\n subheading: field.text({ translatable: true }),\n background: field.media({ accept: ['image/*'] }),\n alignment: field.select({ options: ['left', 'center', 'right'] }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const ImageBlock = defineBlock({\n slug: 'image',\n label: 'Image',\n fields: {\n image: field.media({ accept: ['image/*'], required: true }),\n alt: field.text({ translatable: true }),\n caption: field.text({ translatable: true }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const QuoteBlock = defineBlock({\n slug: 'quote',\n label: 'Quote',\n fields: {\n quote: field.text({ required: true, translatable: true }),\n attribution: field.text({ translatable: true }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const RichTextBlock = defineBlock({\n slug: 'richtext',\n label: 'Rich Text',\n fields: {\n content: field.richtext({ translatable: true }),\n },\n})\n","import { field } from '@murumets-ee/entity'\nimport { defineBlock } from '../define-block.js'\n\nexport const VideoBlock = defineBlock({\n slug: 'video',\n label: 'Video',\n fields: {\n url: field.text({ required: true }),\n poster: field.media({ accept: ['image/*'] }),\n caption: field.text({ translatable: true }),\n },\n})\n","export { CodeBlock } from './code.js'\nexport { CTABlock } from './cta.js'\nexport { GalleryBlock } from './gallery.js'\nexport { HeroBlock } from './hero.js'\nexport { ImageBlock } from './image.js'\nexport { QuoteBlock } from './quote.js'\nexport { RichTextBlock } from './richtext.js'\nexport { VideoBlock } from './video.js'\n\nimport { CodeBlock } from './code.js'\nimport { CTABlock } from './cta.js'\nimport { GalleryBlock } from './gallery.js'\nimport { HeroBlock } from './hero.js'\nimport { ImageBlock } from './image.js'\nimport { QuoteBlock } from './quote.js'\nimport { RichTextBlock } from './richtext.js'\nimport { VideoBlock } from './video.js'\n\n/**\n * All common blocks shipped with the toolkit.\n * Use as-is or pick individual blocks from the named exports.\n *\n * @example\n * import { commonBlocks } from '@murumets-ee/content/blocks'\n * const Page = defineEntity({\n * name: 'page',\n * fields: {\n * layout: field.blocks({ blocks: [...commonBlocks] }),\n * },\n * })\n */\nexport const commonBlocks = [\n RichTextBlock,\n ImageBlock,\n HeroBlock,\n GalleryBlock,\n CTABlock,\n VideoBlock,\n QuoteBlock,\n CodeBlock,\n] as const\n"],"mappings":"6FAGA,MAAa,EAAY,EAAY,CACnC,KAAM,OACN,MAAO,OACP,OAAQ,CACN,KAAM,EAAM,KAAK,CAAE,SAAU,GAAM,CAAC,CACpC,SAAU,EAAM,OAAO,CACrB,QAAS,CACP,aACA,aACA,SACA,OACA,MACA,OACA,OACA,MACA,QACD,CACF,CAAC,CACH,CACF,CAAC,CCnBW,EAAW,EAAY,CAClC,KAAM,MACN,MAAO,iBACP,OAAQ,CACN,QAAS,EAAM,KAAK,CAAE,SAAU,GAAM,aAAc,GAAM,CAAC,CAC3D,YAAa,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CAC/C,WAAY,EAAM,KAAK,CAAE,SAAU,GAAM,aAAc,GAAM,CAAC,CAC9D,WAAY,EAAM,KAAK,CAAE,SAAU,GAAM,CAAC,CAC3C,CACF,CAAC,CCTW,EAAe,EAAY,CACtC,KAAM,UACN,MAAO,UACP,OAAQ,CACN,OAAQ,EAAM,UAAU,CAAE,OAAQ,QAAS,YAAa,OAAQ,CAAC,CACjE,QAAS,EAAM,OAAO,CAAE,QAAS,CAAC,IAAK,IAAK,IAAI,CAAE,CAAC,CACpD,CACF,CAAC,CCPW,EAAY,EAAY,CACnC,KAAM,OACN,MAAO,eACP,OAAQ,CACN,QAAS,EAAM,KAAK,CAAE,SAAU,GAAM,aAAc,GAAM,CAAC,CAC3D,WAAY,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CAC9C,WAAY,EAAM,MAAM,CAAE,OAAQ,CAAC,UAAU,CAAE,CAAC,CAChD,UAAW,EAAM,OAAO,CAAE,QAAS,CAAC,OAAQ,SAAU,QAAQ,CAAE,CAAC,CAClE,CACF,CAAC,CCTW,EAAa,EAAY,CACpC,KAAM,QACN,MAAO,QACP,OAAQ,CACN,MAAO,EAAM,MAAM,CAAE,OAAQ,CAAC,UAAU,CAAE,SAAU,GAAM,CAAC,CAC3D,IAAK,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CACvC,QAAS,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CAC5C,CACF,CAAC,CCRW,EAAa,EAAY,CACpC,KAAM,QACN,MAAO,QACP,OAAQ,CACN,MAAO,EAAM,KAAK,CAAE,SAAU,GAAM,aAAc,GAAM,CAAC,CACzD,YAAa,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CAChD,CACF,CAAC,CCPW,EAAgB,EAAY,CACvC,KAAM,WACN,MAAO,YACP,OAAQ,CACN,QAAS,EAAM,SAAS,CAAE,aAAc,GAAM,CAAC,CAChD,CACF,CAAC,CCNW,EAAa,EAAY,CACpC,KAAM,QACN,MAAO,QACP,OAAQ,CACN,IAAK,EAAM,KAAK,CAAE,SAAU,GAAM,CAAC,CACnC,OAAQ,EAAM,MAAM,CAAE,OAAQ,CAAC,UAAU,CAAE,CAAC,CAC5C,QAAS,EAAM,KAAK,CAAE,aAAc,GAAM,CAAC,CAC5C,CACF,CAAC,CCoBW,EAAe,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACD"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { d as TranslationStatus, f as VersionEntry, r as DraftEntry, s as LocalePublishStatus, u as TranslationReport } from "./types-wLHyjcWf.mjs";
|
|
2
|
+
import { i as FieldDiff } from "./types-nXbE5Ufa.mjs";
|
|
3
|
+
import { Entity, FieldConfig, FieldToTS } from "@murumets-ee/entity";
|
|
4
|
+
import { Logger } from "@murumets-ee/core";
|
|
5
|
+
import { FindManyOptions } from "@murumets-ee/entity/admin";
|
|
6
|
+
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
7
|
+
|
|
8
|
+
//#region src/client.d.ts
|
|
9
|
+
/** Value type that any entity field can hold */
|
|
10
|
+
type EntityFieldValue = FieldToTS<FieldConfig> | null | undefined;
|
|
11
|
+
interface ContentClientConfig {
|
|
12
|
+
entity: Entity;
|
|
13
|
+
db: PostgresJsDatabase;
|
|
14
|
+
logger?: Logger;
|
|
15
|
+
}
|
|
16
|
+
declare class ContentClient {
|
|
17
|
+
private entity;
|
|
18
|
+
private db;
|
|
19
|
+
private logger?;
|
|
20
|
+
private admin;
|
|
21
|
+
private versionableOptions;
|
|
22
|
+
constructor(config: ContentClientConfig);
|
|
23
|
+
private getAdmin;
|
|
24
|
+
create(data: Record<string, EntityFieldValue>): Promise<{
|
|
25
|
+
id: string;
|
|
26
|
+
} & {} & {
|
|
27
|
+
[x: string]: string | number | boolean | Record<string, unknown> | Date | Record<string, unknown>[] | {
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
_block: string;
|
|
30
|
+
_id: string;
|
|
31
|
+
}[] | null | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
findById(id: string, options?: {
|
|
34
|
+
locale?: string;
|
|
35
|
+
}): Promise<({
|
|
36
|
+
id: string;
|
|
37
|
+
} & {} & {
|
|
38
|
+
[x: string]: string | number | boolean | Record<string, unknown> | Date | Record<string, unknown>[] | {
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
_block: string;
|
|
41
|
+
_id: string;
|
|
42
|
+
}[] | null | undefined;
|
|
43
|
+
}) | null>;
|
|
44
|
+
findMany(options?: FindManyOptions): Promise<({
|
|
45
|
+
id: string;
|
|
46
|
+
} & {} & {
|
|
47
|
+
[x: string]: string | number | boolean | Record<string, unknown> | Date | Record<string, unknown>[] | {
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
_block: string;
|
|
50
|
+
_id: string;
|
|
51
|
+
}[] | null | undefined;
|
|
52
|
+
})[]>;
|
|
53
|
+
update(id: string, data: Record<string, EntityFieldValue>): Promise<{
|
|
54
|
+
id: string;
|
|
55
|
+
} & {} & {
|
|
56
|
+
[x: string]: string | number | boolean | Record<string, unknown> | Date | Record<string, unknown>[] | {
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
_block: string;
|
|
59
|
+
_id: string;
|
|
60
|
+
}[] | null | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
delete(id: string): Promise<void>;
|
|
63
|
+
saveTranslation(entityId: string, locale: string, translations: Record<string, unknown>): Promise<void>;
|
|
64
|
+
deleteTranslation(entityId: string, locale?: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Copy layout from one locale to another (for localized: true blocks).
|
|
67
|
+
*/
|
|
68
|
+
copyLayout(entityId: string, options: {
|
|
69
|
+
from: string;
|
|
70
|
+
to: string | string[];
|
|
71
|
+
}): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* List versions for an entity (newest first), filtered by locale.
|
|
74
|
+
* Uses '_' as the locale value for default-locale snapshots.
|
|
75
|
+
*/
|
|
76
|
+
getVersions(entityId: string, options?: {
|
|
77
|
+
limit?: number;
|
|
78
|
+
offset?: number;
|
|
79
|
+
locale?: string;
|
|
80
|
+
}): Promise<VersionEntry[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Get a specific version snapshot.
|
|
83
|
+
*/
|
|
84
|
+
getVersion(entityId: string, version: number, locale?: string): Promise<VersionEntry | null>;
|
|
85
|
+
/**
|
|
86
|
+
* Compare two versions and return field-level diff.
|
|
87
|
+
*
|
|
88
|
+
* Returns structured diffs with word-level segments for text fields
|
|
89
|
+
* and structural block diffs for blocks fields.
|
|
90
|
+
*/
|
|
91
|
+
compareVersions(entityId: string, v1: number, v2: number, locale?: string): Promise<{
|
|
92
|
+
diffs: FieldDiff[];
|
|
93
|
+
fromVersion: VersionEntry;
|
|
94
|
+
toVersion: VersionEntry;
|
|
95
|
+
} | null>;
|
|
96
|
+
/**
|
|
97
|
+
* Compare the current draft with the live entity (or a specific version).
|
|
98
|
+
* Returns field-level diffs between the current published data and the draft.
|
|
99
|
+
*/
|
|
100
|
+
compareDraftWithCurrent(entityId: string, locale?: string): Promise<{
|
|
101
|
+
diffs: FieldDiff[];
|
|
102
|
+
current: Record<string, unknown>;
|
|
103
|
+
draft: DraftEntry;
|
|
104
|
+
} | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Restore an entity to a previous version.
|
|
107
|
+
*/
|
|
108
|
+
restoreVersion(entityId: string, version: number): Promise<{
|
|
109
|
+
id: string;
|
|
110
|
+
} & {} & {
|
|
111
|
+
[x: string]: string | number | boolean | Record<string, unknown> | Date | Record<string, unknown>[] | {
|
|
112
|
+
[key: string]: unknown;
|
|
113
|
+
_block: string;
|
|
114
|
+
_id: string;
|
|
115
|
+
}[] | null | undefined;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Enforce maxPerDoc retention by deleting oldest versions for a locale.
|
|
119
|
+
*/
|
|
120
|
+
pruneVersions(entityId: string, locale?: string): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Get translation status for an entity — per-locale completion report.
|
|
123
|
+
*/
|
|
124
|
+
getTranslationStatus(entityId: string): Promise<TranslationStatus>;
|
|
125
|
+
/**
|
|
126
|
+
* Get translation status for multiple entities in a single query.
|
|
127
|
+
* Returns a map of entityId → TranslationStatus (O(1) DB roundtrips).
|
|
128
|
+
*/
|
|
129
|
+
getTranslationStatusBatch(entityIds: string[]): Promise<Map<string, TranslationStatus>>;
|
|
130
|
+
/**
|
|
131
|
+
* Get translation report across all entities of this type.
|
|
132
|
+
*/
|
|
133
|
+
getTranslationReport(options?: {
|
|
134
|
+
locale?: string;
|
|
135
|
+
}): Promise<TranslationReport>;
|
|
136
|
+
/**
|
|
137
|
+
* Get per-locale publish status for an entity.
|
|
138
|
+
* Returns status for all non-default locales that have explicit overrides.
|
|
139
|
+
* Missing locale = inherits base entity status.
|
|
140
|
+
*/
|
|
141
|
+
getLocaleStatus(entityId: string): Promise<LocalePublishStatus[]>;
|
|
142
|
+
/**
|
|
143
|
+
* Set per-locale publish status. Upserts into locale_status table.
|
|
144
|
+
* When locale === defaultLocale, updates the base entity status instead.
|
|
145
|
+
*/
|
|
146
|
+
setLocaleStatus(entityId: string, locale: string, status: 'draft' | 'published'): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Get per-locale publish status for multiple entities in a single query.
|
|
149
|
+
* Returns a map of entityId → locale → LocalePublishStatus.
|
|
150
|
+
*/
|
|
151
|
+
getLocaleStatusBatch(entityIds: string[]): Promise<Map<string, Record<string, LocalePublishStatus>>>;
|
|
152
|
+
/**
|
|
153
|
+
* Save (upsert) a draft for an entity+locale.
|
|
154
|
+
* One draft per entity+locale — overwrites any existing draft.
|
|
155
|
+
*/
|
|
156
|
+
saveDraft(entityId: string, data: Record<string, unknown>, locale?: string, user?: {
|
|
157
|
+
id: string;
|
|
158
|
+
name?: string;
|
|
159
|
+
}): Promise<DraftEntry>;
|
|
160
|
+
/**
|
|
161
|
+
* Get the draft for an entity+locale, or null if none exists.
|
|
162
|
+
*/
|
|
163
|
+
getDraft(entityId: string, locale?: string): Promise<DraftEntry | null>;
|
|
164
|
+
/**
|
|
165
|
+
* Delete (discard) a draft for an entity+locale.
|
|
166
|
+
*/
|
|
167
|
+
deleteDraft(entityId: string, locale?: string): Promise<boolean>;
|
|
168
|
+
/**
|
|
169
|
+
* Publish a draft: apply draft data to the live entity, then delete the draft.
|
|
170
|
+
* Runs in a transaction to ensure atomicity.
|
|
171
|
+
*/
|
|
172
|
+
publishDraft(entityId: string, locale?: string, user?: {
|
|
173
|
+
id: string;
|
|
174
|
+
name?: string;
|
|
175
|
+
}): Promise<Record<string, unknown>>;
|
|
176
|
+
/**
|
|
177
|
+
* Quick existence check for list badges — does a draft exist?
|
|
178
|
+
*/
|
|
179
|
+
hasDraft(entityId: string, locale?: string): Promise<boolean>;
|
|
180
|
+
/**
|
|
181
|
+
* Count drafts for this entity type, optionally filtered by locale.
|
|
182
|
+
* Single indexed COUNT query — used by dashboard widgets.
|
|
183
|
+
*/
|
|
184
|
+
countDrafts(locale?: string): Promise<number>;
|
|
185
|
+
/**
|
|
186
|
+
* Check draft existence for multiple entities in one query.
|
|
187
|
+
* Returns a set of entity IDs that have drafts.
|
|
188
|
+
*/
|
|
189
|
+
hasDraftBatch(entityIds: string[], locale?: string): Promise<Set<string>>;
|
|
190
|
+
/**
|
|
191
|
+
* Create a version snapshot for an entity after an external update.
|
|
192
|
+
* Use this when the update was performed by AdminClient directly
|
|
193
|
+
* (e.g., the admin API handler) rather than through ContentClient.update().
|
|
194
|
+
*
|
|
195
|
+
* @param locale - The locale being edited. Use undefined or '_' for the default locale.
|
|
196
|
+
* @param user - The user who made the change (id + name for display).
|
|
197
|
+
*/
|
|
198
|
+
createVersionSnapshot(entityId: string, currentData: Record<string, unknown>, previousData?: Record<string, unknown> | null, locale?: string, user?: {
|
|
199
|
+
id: string;
|
|
200
|
+
name?: string;
|
|
201
|
+
}): Promise<void>;
|
|
202
|
+
private saveVersionSnapshot;
|
|
203
|
+
private toDraftEntry;
|
|
204
|
+
private calculateDelta;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Factory — creates a ContentClient for an entity.
|
|
208
|
+
* Must be called after createApp().
|
|
209
|
+
*/
|
|
210
|
+
declare function createContentClient(entity: Entity): Promise<ContentClient>;
|
|
211
|
+
//#endregion
|
|
212
|
+
export { ContentClient, ContentClientConfig, createContentClient };
|
|
213
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":"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"}
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{o as e,r as t,t as n}from"./block-diff-H1AttKiz.mjs";import"server-only";var r=class{entity;db;logger;admin=null;versionableOptions;constructor(t){this.entity=t.entity,this.db=t.db,this.logger=t.logger,this.versionableOptions=e(t.entity.behaviors)}async getAdmin(){if(!this.admin){let{AdminClient:e}=await import(`@murumets-ee/entity/admin`);this.admin=new e({entity:this.entity,db:this.db,logger:this.logger})}return this.admin}async create(e){let t=await(await this.getAdmin()).create(e);return this.versionableOptions&&await this.saveVersionSnapshot(t.id,t,null,!1),t}async findById(e,t){return(await this.getAdmin()).findById(e,t)}async findMany(e){return(await this.getAdmin()).findMany(e)}async update(e,t){let n=await this.getAdmin(),r=null;this.versionableOptions&&(r=await n.findById(e));let i=await n.update(e,t);if(this.versionableOptions&&r){let t=this.calculateDelta(r,i),n=await this.saveVersionSnapshot(e,i,t,!1);if(n!==void 0){let{schemaRegistry:t}=await import(`@murumets-ee/db`),{eq:r}=await import(`drizzle-orm`),a=t.get(this.entity.name);a&&(await this.db.update(a).set({_version:n}).where(r(a.id,e)),i._version=n)}await this.pruneVersions(e)}return i}async delete(e){return(await this.getAdmin()).delete(e)}async saveTranslation(e,t,n){return(await this.getAdmin()).saveTranslation(e,t,n)}async deleteTranslation(e,t){return(await this.getAdmin()).deleteTranslation(e,t)}async copyLayout(e,t){let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i}=await import(`drizzle-orm`),a=n.get(`${this.entity.name}_layout`);if(!a)return;let o=Array.isArray(t.to)?t.to:[t.to],s=await this.db.select().from(a).where(i(r(a.entityId,e),r(a.locale,t.from))).orderBy(a.sortOrder);if(s.length!==0){for(let t of o){await this.db.delete(a).where(i(r(a.entityId,e),r(a.locale,t)));for(let e of s)await this.db.insert(a).values({entityId:e.entityId,fieldName:e.fieldName,blockType:e.blockType,sortOrder:e.sortOrder,data:e.data,locale:t})}this.logger?.debug({entityId:e,from:t.from,to:o},`Layout copied between locales`)}}async getVersions(e,t){let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i,desc:a}=await import(`drizzle-orm`),o=n.get(`${this.entity.name}_versions`);if(!o)return[];let s=t?.locale??`_`,c=this.db.select().from(o).where(i(r(o.entityId,e),r(o.locale,s))).orderBy(a(o.version)).$dynamic();return t?.limit&&(c=c.limit(t.limit)),t?.offset&&(c=c.offset(t.offset)),c}async getVersion(e,t,n=`_`){let{schemaRegistry:r}=await import(`@murumets-ee/db`),{eq:i,and:a}=await import(`drizzle-orm`),o=r.get(`${this.entity.name}_versions`);return o?(await this.db.select().from(o).where(a(i(o.entityId,e),i(o.version,t),i(o.locale,n))).limit(1))[0]??null:null}async compareVersions(e,r,i,a=`_`){let[o,s]=await Promise.all([this.getVersion(e,r,a),this.getVersion(e,i,a)]);if(!o||!s)return null;let c=o.data,l=s.data,u=this.entity.allFields,d=t(c,l,u);for(let e of d)e.type===`blocks`&&Array.isArray(e.from)&&Array.isArray(e.to)&&(e.blockDiffs=n(e.from,e.to));return{diffs:d,fromVersion:o,toVersion:s}}async compareDraftWithCurrent(e,r=`_`){let i=await this.getDraft(e,r);if(!i)return null;let a=await this.getAdmin(),{getContentConfig:o}=await import(`./plugin.mjs`),s=o().defaultLocale,c=r===`_`?{defaultLocale:s}:{locale:r,defaultLocale:s},l=await a.findById(e,c);if(!l)return null;let u=this.entity.allFields,d={};for(let e of Object.keys(i.data))d[e]=l[e];let f=t(d,i.data,u);for(let e of f)e.type===`blocks`&&Array.isArray(e.from)&&Array.isArray(e.to)&&(e.blockDiffs=n(e.from,e.to));return{diffs:f,current:l,draft:i}}async restoreVersion(e,t){let n=await this.getVersion(e,t);if(!n)throw Error(`Version ${t} not found for entity ${e}`);let{id:r,createdAt:i,createdBy:a,_version:o,_versionedAt:s,...c}=n.data;return(await this.getAdmin()).update(e,c)}async pruneVersions(e,t=`_`){if(!this.versionableOptions)return;let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i,desc:a,sql:o}=await import(`drizzle-orm`),s=n.get(`${this.entity.name}_versions`);if(!s)return;let c=this.versionableOptions.maxPerDoc,l=await this.db.select({id:s.id}).from(s).where(i(r(s.entityId,e),r(s.locale,t))).orderBy(a(s.version)).limit(c);if(l.length<c)return;let u=l.map(e=>e.id);await this.db.delete(s).where(o`${s.entityId} = ${e} AND ${s.locale} = ${t} AND ${s.id} NOT IN (${o.join(u.map(e=>o`${e}`),o`, `)})`)}async getTranslationStatus(e){let{getContentConfig:t}=await import(`./plugin.mjs`),n=t(),r=Object.entries(this.entity.allFields).filter(([e,t])=>t.translatable).map(([e])=>e);if(r.length===0)return{};let{schemaRegistry:i}=await import(`@murumets-ee/db`),{eq:a}=await import(`drizzle-orm`),o=i.get(`${this.entity.name}_translations`);if(!o)return{};let s=await this.db.select().from(o).where(a(o.entityId,e)),c=new Map;for(let e of s){let t=e,n={};for(let e of r)n[e]=t[e];c.set(t.locale,n)}let l={};for(let e of n.locales){if(e.code===n.defaultLocale)continue;let t=c.get(e.code)??{},i=[];for(let e of r)(t[e]===void 0||t[e]===null)&&i.push(e);let a=r.length-i.length;l[e.code]={complete:i.length===0,total:r.length,translated:a,missing:i}}return l}async getTranslationStatusBatch(e){let t=new Map;if(e.length===0)return t;let{getContentConfig:n}=await import(`./plugin.mjs`),r=n(),i=Object.entries(this.entity.allFields).filter(([e,t])=>t.translatable).map(([e])=>e);if(i.length===0)return t;let{schemaRegistry:a}=await import(`@murumets-ee/db`),{inArray:o}=await import(`drizzle-orm`),s=a.get(`${this.entity.name}_translations`);if(!s)return t;let c=await this.db.select().from(s).where(o(s.entityId,e)),l=new Map;for(let e of c){let t=e,n=t.entityId,r=t.locale,a={};for(let e of i)a[e]=t[e];l.has(n)||l.set(n,new Map),l.get(n).set(r,a)}for(let n of e){let e=l.get(n),a={};for(let t of r.locales){if(t.code===r.defaultLocale)continue;let n=e?.get(t.code)??{},o=[];for(let e of i)(n[e]===void 0||n[e]===null)&&o.push(e);let s=i.length-o.length;a[t.code]={complete:o.length===0,total:i.length,translated:s,missing:o}}t.set(n,a)}return t}async getTranslationReport(e){let{getContentConfig:t}=await import(`./plugin.mjs`),n=t(),r=e?.locale??n.locales.find(e=>e.code!==n.defaultLocale)?.code;if(!r)return{total:0,complete:0,partial:0,missing:0};let i=await(await this.getAdmin()).findMany(),a=0,o=0,s=0;for(let e of i){let t=(await this.getTranslationStatus(e.id))[r];!t||t.translated===0?s++:t.complete?a++:o++}return{total:i.length,complete:a,partial:o,missing:s}}async getLocaleStatus(e){let{schemaRegistry:t}=await import(`@murumets-ee/db`),{eq:n}=await import(`drizzle-orm`),r=t.get(`${this.entity.name}_locale_status`);return r?(await this.db.select().from(r).where(n(r.entityId,e))).map(e=>({locale:e.locale,status:e.status,publishedAt:e.publishedAt??null})):[]}async setLocaleStatus(e,t,n){let{getContentConfig:r}=await import(`./plugin.mjs`);if(t===r().defaultLocale){let t=await this.getAdmin(),r={status:n};n===`published`&&(r.publishedAt=new Date),await t.update(e,r);return}let{schemaRegistry:i}=await import(`@murumets-ee/db`),{eq:a,and:o}=await import(`drizzle-orm`),s=i.get(`${this.entity.name}_locale_status`);if(!s)return;let c=n===`published`?new Date:null,[l]=await this.db.select({id:s.id}).from(s).where(o(a(s.entityId,e),a(s.locale,t))).limit(1);l?await this.db.update(s).set({status:n,publishedAt:c}).where(a(s.id,l.id)):await this.db.insert(s).values({entityId:e,locale:t,status:n,publishedAt:c})}async getLocaleStatusBatch(e){let t=new Map;if(e.length===0)return t;let{schemaRegistry:n}=await import(`@murumets-ee/db`),{inArray:r}=await import(`drizzle-orm`),i=n.get(`${this.entity.name}_locale_status`);if(!i)return t;let a=await this.db.select().from(i).where(r(i.entityId,e));for(let e of a){let n=e.entityId,r=e.locale;t.has(n)||t.set(n,{}),t.get(n)[r]={locale:r,status:e.status,publishedAt:e.publishedAt??null}}return t}async saveDraft(e,t,n=`_`,r){let{schemaRegistry:i}=await import(`@murumets-ee/db`),{eq:a,and:o}=await import(`drizzle-orm`),s=i.get(`${this.entity.name}_drafts`);if(!s)throw Error(`Drafts table not found for entity "${this.entity.name}". Is the content plugin initialized?`);let c=new Date,l=r?.id??``,u=r?.name??null,[d]=await this.db.select().from(s).where(o(a(s.entityId,e),a(s.locale,n))).limit(1);if(d){let[e]=await this.db.update(s).set({data:t,updatedAt:c}).where(a(s.id,d.id)).returning();return this.toDraftEntry(e)}let[f]=await this.db.insert(s).values({entityId:e,locale:n,data:t,createdBy:l,createdByName:u,createdAt:c,updatedAt:c}).returning();return this.toDraftEntry(f)}async getDraft(e,t=`_`){let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i}=await import(`drizzle-orm`),a=n.get(`${this.entity.name}_drafts`);if(!a)return null;let[o]=await this.db.select().from(a).where(i(r(a.entityId,e),r(a.locale,t))).limit(1);return o?this.toDraftEntry(o):null}async deleteDraft(e,t=`_`){let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i}=await import(`drizzle-orm`),a=n.get(`${this.entity.name}_drafts`);return a?(await this.db.delete(a).where(i(r(a.entityId,e),r(a.locale,t))).returning({id:a.id})).length>0:!1}async publishDraft(e,t=`_`,n){let r=await this.getDraft(e,t);if(!r)throw Error(`No draft found for entity ${e} locale ${t}`);let i=await this.getAdmin(),a=null;this.versionableOptions&&(a=await i.findById(e));let{id:o,createdAt:s,createdBy:c,_version:l,_versionedAt:u,...d}=r.data,f=await i.update(e,d);return await this.deleteDraft(e,t),this.versionableOptions&&await this.createVersionSnapshot(e,f,a,t,n),f}async hasDraft(e,t=`_`){let{schemaRegistry:n}=await import(`@murumets-ee/db`),{eq:r,and:i}=await import(`drizzle-orm`),a=n.get(`${this.entity.name}_drafts`);if(!a)return!1;let[o]=await this.db.select({id:a.id}).from(a).where(i(r(a.entityId,e),r(a.locale,t))).limit(1);return!!o}async countDrafts(e=`_`){let{schemaRegistry:t}=await import(`@murumets-ee/db`),{eq:n,sql:r}=await import(`drizzle-orm`),i=t.get(`${this.entity.name}_drafts`);if(!i)return 0;let[a]=await this.db.select({count:r`count(*)::int`}).from(i).where(n(i.locale,e));return a?.count??0}async hasDraftBatch(e,t=`_`){let n=new Set;if(e.length===0)return n;let{schemaRegistry:r}=await import(`@murumets-ee/db`),{inArray:i,eq:a,and:o}=await import(`drizzle-orm`),s=r.get(`${this.entity.name}_drafts`);if(!s)return n;let c=await this.db.select({entityId:s.entityId}).from(s).where(o(i(s.entityId,e),a(s.locale,t)));for(let e of c)n.add(e.entityId);return n}async createVersionSnapshot(e,t,n,r,i){if(!this.versionableOptions)return;let a=r??`_`,o=n?this.calculateDelta(n,t):null,s=await this.saveVersionSnapshot(e,t,o,!1,a,i);if(s!==void 0&&a===`_`){let{schemaRegistry:t}=await import(`@murumets-ee/db`),{eq:n}=await import(`drizzle-orm`),r=t.get(this.entity.name);r&&await this.db.update(r).set({_version:s}).where(n(r.id,e))}await this.pruneVersions(e,a)}async saveVersionSnapshot(e,t,n,r,i=`_`,a){let{schemaRegistry:o}=await import(`@murumets-ee/db`),{eq:s,and:c,sql:l}=await import(`drizzle-orm`),u=o.get(`${this.entity.name}_versions`);if(!u)return;let[d]=await this.db.select({maxVersion:l`coalesce(max(${u.version}), 0)`}).from(u).where(c(s(u.entityId,e),s(u.locale,i))),f=(d?.maxVersion??0)+1,p=t.status??null;if(r){let[r]=await this.db.select().from(u).where(c(s(u.entityId,e),s(u.isAutosave,!0),s(u.version,f),s(u.locale,i))).limit(1);if(r)return await this.db.update(u).set({data:t,delta:n,status:p,createdAt:new Date}).where(s(u.id,r.id)),f}return await this.db.insert(u).values({entityId:e,version:f,locale:i,data:t,delta:n,status:p,createdBy:a?.id??t.updatedBy??t.createdBy??null,createdByName:a?.name??null,isAutosave:r}),f}toDraftEntry(e){return{id:e.id,entityId:e.entityId,locale:e.locale,data:e.data,createdBy:e.createdBy,createdByName:e.createdByName??null,createdAt:e.createdAt,updatedAt:e.updatedAt}}calculateDelta(e,t){let n={};for(let r of Object.keys(t))r===`id`||r.startsWith(`_`)||JSON.stringify(e[r])!==JSON.stringify(t[r])&&(n[r]=t[r]);return n}};async function i(e){let{getApp:t}=await import(`@murumets-ee/core`),n=t();return new r({entity:e,db:n.db.readWrite,logger:n.logger.child({content:e.name})})}export{r as ContentClient,i as createContentClient};
|
|
2
|
+
//# sourceMappingURL=client.mjs.map
|