@murumets-ee/content 0.25.0 → 0.26.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.
Files changed (43) hide show
  1. package/dist/client.d.mts +21 -18
  2. package/dist/client.d.mts.map +1 -1
  3. package/dist/client.mjs +1 -1
  4. package/dist/client.mjs.map +1 -1
  5. package/dist/entities/index.d.mts +1 -1
  6. package/dist/errors-DLvszZ9R.mjs +2 -0
  7. package/dist/errors-DLvszZ9R.mjs.map +1 -0
  8. package/dist/{index-CB0fdMs1.d.mts → index-C9EWajwm.d.mts} +21 -14
  9. package/dist/index-C9EWajwm.d.mts.map +1 -0
  10. package/dist/index.d.mts +3 -3
  11. package/dist/index.mjs +1 -1
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/locale-utils-q7qYD-ff.mjs +2 -0
  14. package/dist/locale-utils-q7qYD-ff.mjs.map +1 -0
  15. package/dist/lock-service.d.mts +1 -1
  16. package/dist/lock-service.mjs +1 -1
  17. package/dist/{locks-BCHUb-yC.mjs → locks-BRtmYqgS.mjs} +1 -1
  18. package/dist/{locks-BCHUb-yC.mjs.map → locks-BRtmYqgS.mjs.map} +1 -1
  19. package/dist/plugin-ppoIGq-c.mjs +2 -0
  20. package/dist/plugin-ppoIGq-c.mjs.map +1 -0
  21. package/dist/plugin.d.mts +1 -1
  22. package/dist/plugin.d.mts.map +1 -1
  23. package/dist/plugin.mjs +1 -1
  24. package/dist/query-client.d.mts +15 -9
  25. package/dist/query-client.d.mts.map +1 -1
  26. package/dist/query-client.mjs +1 -1
  27. package/dist/{types-CWo2dfEK.d.mts → types-BhMSxasE.d.mts} +3 -28
  28. package/dist/types-BhMSxasE.d.mts.map +1 -0
  29. package/package.json +8 -10
  30. package/dist/blocks/index.d.mts +0 -196
  31. package/dist/blocks/index.d.mts.map +0 -1
  32. package/dist/blocks/index.mjs +0 -2
  33. package/dist/blocks/index.mjs.map +0 -1
  34. package/dist/define-block-DpMPEEdA.mjs +0 -2
  35. package/dist/define-block-DpMPEEdA.mjs.map +0 -1
  36. package/dist/errors-CVBrIU1K.mjs +0 -2
  37. package/dist/errors-CVBrIU1K.mjs.map +0 -1
  38. package/dist/index-CB0fdMs1.d.mts.map +0 -1
  39. package/dist/locale-utils-DIcmuLIr.mjs +0 -2
  40. package/dist/locale-utils-DIcmuLIr.mjs.map +0 -1
  41. package/dist/plugin-DbK6FxTd.mjs +0 -2
  42. package/dist/plugin-DbK6FxTd.mjs.map +0 -1
  43. package/dist/types-CWo2dfEK.d.mts.map +0 -1
@@ -1,196 +0,0 @@
1
- import { t as BlockDefinition } from "../types-CWo2dfEK.mjs";
2
-
3
- //#region src/blocks/code.d.ts
4
- declare const CodeBlock: BlockDefinition<{
5
- readonly code: import("@murumets-ee/entity").TextField & {
6
- readonly required: true;
7
- };
8
- readonly language: import("@murumets-ee/entity").SelectField & {
9
- options: readonly ["javascript", "typescript", "python", "html", "css", "json", "bash", "sql", "other"];
10
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
11
- }>;
12
- //#endregion
13
- //#region src/blocks/cta.d.ts
14
- declare const CTABlock: BlockDefinition<{
15
- readonly heading: import("@murumets-ee/entity").TextField & {
16
- readonly required: true;
17
- readonly translatable: true;
18
- };
19
- readonly description: import("@murumets-ee/entity").TextField & {
20
- readonly translatable: true;
21
- };
22
- readonly buttonText: import("@murumets-ee/entity").TextField & {
23
- readonly required: true;
24
- readonly translatable: true;
25
- };
26
- readonly buttonLink: import("@murumets-ee/entity").TextField & {
27
- readonly required: true;
28
- };
29
- }>;
30
- //#endregion
31
- //#region src/blocks/gallery.d.ts
32
- declare const GalleryBlock: BlockDefinition<{
33
- readonly images: import("@murumets-ee/entity").ReferenceField & {
34
- cardinality: "many";
35
- } & Partial<Omit<import("@murumets-ee/entity").ReferenceField, "cardinality" | "entity">>;
36
- readonly columns: import("@murumets-ee/entity").SelectField & {
37
- options: readonly ["2", "3", "4"];
38
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
39
- }>;
40
- //#endregion
41
- //#region src/blocks/hero.d.ts
42
- declare const HeroBlock: BlockDefinition<{
43
- readonly heading: import("@murumets-ee/entity").TextField & {
44
- readonly required: true;
45
- readonly translatable: true;
46
- };
47
- readonly subheading: import("@murumets-ee/entity").TextField & {
48
- readonly translatable: true;
49
- };
50
- readonly background: import("@murumets-ee/entity").MediaField & {
51
- readonly accept: ["image/*"];
52
- };
53
- readonly alignment: import("@murumets-ee/entity").SelectField & {
54
- options: readonly ["left", "center", "right"];
55
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
56
- }>;
57
- //#endregion
58
- //#region src/blocks/image.d.ts
59
- declare const ImageBlock: BlockDefinition<{
60
- readonly image: import("@murumets-ee/entity").MediaField & {
61
- readonly accept: ["image/*"];
62
- readonly required: true;
63
- };
64
- readonly alt: import("@murumets-ee/entity").TextField & {
65
- readonly translatable: true;
66
- };
67
- readonly caption: import("@murumets-ee/entity").TextField & {
68
- readonly translatable: true;
69
- };
70
- }>;
71
- //#endregion
72
- //#region src/blocks/quote.d.ts
73
- declare const QuoteBlock: BlockDefinition<{
74
- readonly quote: import("@murumets-ee/entity").TextField & {
75
- readonly required: true;
76
- readonly translatable: true;
77
- };
78
- readonly attribution: import("@murumets-ee/entity").TextField & {
79
- readonly translatable: true;
80
- };
81
- }>;
82
- //#endregion
83
- //#region src/blocks/richtext.d.ts
84
- declare const RichTextBlock: BlockDefinition<{
85
- readonly content: import("@murumets-ee/entity").RichTextField & {
86
- readonly translatable: true;
87
- };
88
- }>;
89
- //#endregion
90
- //#region src/blocks/video.d.ts
91
- declare const VideoBlock: BlockDefinition<{
92
- readonly url: import("@murumets-ee/entity").TextField & {
93
- readonly required: true;
94
- };
95
- readonly poster: import("@murumets-ee/entity").MediaField & {
96
- readonly accept: ["image/*"];
97
- };
98
- readonly caption: import("@murumets-ee/entity").TextField & {
99
- readonly translatable: true;
100
- };
101
- }>;
102
- //#endregion
103
- //#region src/blocks/index.d.ts
104
- /**
105
- * All common blocks shipped with the toolkit.
106
- * Use as-is or pick individual blocks from the named exports.
107
- *
108
- * @example
109
- * import { commonBlocks } from '@murumets-ee/content/blocks'
110
- * const Page = defineEntity({
111
- * name: 'page',
112
- * fields: {
113
- * layout: field.blocks({ blocks: [...commonBlocks] }),
114
- * },
115
- * })
116
- */
117
- declare const commonBlocks: readonly [BlockDefinition<{
118
- readonly content: import("@murumets-ee/entity").RichTextField & {
119
- readonly translatable: true;
120
- };
121
- }>, BlockDefinition<{
122
- readonly image: import("@murumets-ee/entity").MediaField & {
123
- readonly accept: ["image/*"];
124
- readonly required: true;
125
- };
126
- readonly alt: import("@murumets-ee/entity").TextField & {
127
- readonly translatable: true;
128
- };
129
- readonly caption: import("@murumets-ee/entity").TextField & {
130
- readonly translatable: true;
131
- };
132
- }>, BlockDefinition<{
133
- readonly heading: import("@murumets-ee/entity").TextField & {
134
- readonly required: true;
135
- readonly translatable: true;
136
- };
137
- readonly subheading: import("@murumets-ee/entity").TextField & {
138
- readonly translatable: true;
139
- };
140
- readonly background: import("@murumets-ee/entity").MediaField & {
141
- readonly accept: ["image/*"];
142
- };
143
- readonly alignment: import("@murumets-ee/entity").SelectField & {
144
- options: readonly ["left", "center", "right"];
145
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
146
- }>, BlockDefinition<{
147
- readonly images: import("@murumets-ee/entity").ReferenceField & {
148
- cardinality: "many";
149
- } & Partial<Omit<import("@murumets-ee/entity").ReferenceField, "cardinality" | "entity">>;
150
- readonly columns: import("@murumets-ee/entity").SelectField & {
151
- options: readonly ["2", "3", "4"];
152
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
153
- }>, BlockDefinition<{
154
- readonly heading: import("@murumets-ee/entity").TextField & {
155
- readonly required: true;
156
- readonly translatable: true;
157
- };
158
- readonly description: import("@murumets-ee/entity").TextField & {
159
- readonly translatable: true;
160
- };
161
- readonly buttonText: import("@murumets-ee/entity").TextField & {
162
- readonly required: true;
163
- readonly translatable: true;
164
- };
165
- readonly buttonLink: import("@murumets-ee/entity").TextField & {
166
- readonly required: true;
167
- };
168
- }>, BlockDefinition<{
169
- readonly url: import("@murumets-ee/entity").TextField & {
170
- readonly required: true;
171
- };
172
- readonly poster: import("@murumets-ee/entity").MediaField & {
173
- readonly accept: ["image/*"];
174
- };
175
- readonly caption: import("@murumets-ee/entity").TextField & {
176
- readonly translatable: true;
177
- };
178
- }>, BlockDefinition<{
179
- readonly quote: import("@murumets-ee/entity").TextField & {
180
- readonly required: true;
181
- readonly translatable: true;
182
- };
183
- readonly attribution: import("@murumets-ee/entity").TextField & {
184
- readonly translatable: true;
185
- };
186
- }>, BlockDefinition<{
187
- readonly code: import("@murumets-ee/entity").TextField & {
188
- readonly required: true;
189
- };
190
- readonly language: import("@murumets-ee/entity").SelectField & {
191
- options: readonly ["javascript", "typescript", "python", "html", "css", "json", "bash", "sql", "other"];
192
- } & Omit<Partial<import("@murumets-ee/entity").SelectField>, "options">;
193
- }>];
194
- //#endregion
195
- export { CTABlock, CodeBlock, GalleryBlock, HeroBlock, ImageBlock, QuoteBlock, RichTextBlock, VideoBlock, commonBlocks };
196
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
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;;;;;;;;;;cCAA,QAAA,EASX,eAAA;EAAA;;;;;;;;;;;;;;;;;cCTW,YAAA;;;;;;;;;;cCAA,SAAA;;;;;;;;;;;;;;;;;cCAA,UAAA,EAQX,eAAA;EAAA;;;;;;;;;;;;;cCRW,UAAA,EAOX,eAAA;EAAA;;;;;;;;;;cCPW,aAAA,EAMX,eAAA;EAAA;;;;;;cCNW,UAAA,EAQX,eAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cCoBW,YAAA,YASH,eAAA;EAAA;;;IATe,eAAA;EAAA"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"../define-block-DpMPEEdA.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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- function e(e){if(!e.slug||!e.slug.match(/^[a-z][a-z0-9-]*$/))throw Error(`Block slug must be lowercase alphanumeric with hyphens, got: "${e.slug}"`);if(!e.label)throw Error(`Block label is required for slug: "${e.slug}"`);if(!e.fields||Object.keys(e.fields).length===0)throw Error(`Block "${e.slug}" must have at least one field`);return{slug:e.slug,label:e.label,fields:e.fields}}export{e as t};
2
- //# sourceMappingURL=define-block-DpMPEEdA.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"define-block-DpMPEEdA.mjs","names":[],"sources":["../src/define-block.ts"],"sourcesContent":["/**\n * Block definition API\n *\n * defineBlock() creates a reusable content block with typed fields.\n * Uses `const F` generic to preserve literal field types for inference.\n *\n * Blocks are NOT entities — they lack independent identity, CRUD, and access control.\n * They exist only as embedded data within a parent entity's blocks field.\n *\n * @example\n * const HeroBlock = defineBlock({\n * slug: 'hero',\n * label: 'Hero Section',\n * fields: {\n * heading: field.text({ required: true, translatable: true }),\n * background: field.media({ accept: ['image/*'] }),\n * },\n * })\n */\n\nimport type { FieldConfig } from '@murumets-ee/entity'\nimport type { BlockDefinition } from './types.js'\n\nexport function defineBlock<const F extends Record<string, FieldConfig>>(definition: {\n slug: string\n label: string\n fields: F\n}): BlockDefinition<F> {\n if (!definition.slug || !definition.slug.match(/^[a-z][a-z0-9-]*$/)) {\n throw new Error(\n `Block slug must be lowercase alphanumeric with hyphens, got: \"${definition.slug}\"`,\n )\n }\n\n if (!definition.label) {\n throw new Error(`Block label is required for slug: \"${definition.slug}\"`)\n }\n\n if (!definition.fields || Object.keys(definition.fields).length === 0) {\n throw new Error(`Block \"${definition.slug}\" must have at least one field`)\n }\n\n return {\n slug: definition.slug,\n label: definition.label,\n fields: definition.fields,\n }\n}\n"],"mappings":"AAuBA,SAAgB,EAAyD,EAIlD,CACrB,GAAI,CAAC,EAAW,MAAQ,CAAC,EAAW,KAAK,MAAM,oBAAoB,CACjE,MAAU,MACR,iEAAiE,EAAW,KAAK,GAClF,CAGH,GAAI,CAAC,EAAW,MACd,MAAU,MAAM,sCAAsC,EAAW,KAAK,GAAG,CAG3E,GAAI,CAAC,EAAW,QAAU,OAAO,KAAK,EAAW,OAAO,CAAC,SAAW,EAClE,MAAU,MAAM,UAAU,EAAW,KAAK,gCAAgC,CAG5E,MAAO,CACL,KAAM,EAAW,KACjB,MAAO,EAAW,MAClB,OAAQ,EAAW,OACpB"}
@@ -1,2 +0,0 @@
1
- var e=class extends Error{entityName;capability;constructor(e,t,n){super(n??`Entity "${e}" does not support ${t}. Add the corresponding behavior to defineEntity({ behaviors: [...] }).`),this.name=`EntityCapabilityError`,this.entityName=e,this.capability=t}},t=class extends Error{locale;allowed;constructor(e,t){super(`Invalid locale "${e}". Configured locales: [${t.join(`, `)}]. (The "_" sentinel is also accepted for default-locale storage.)`),this.name=`InvalidLocaleError`,this.locale=e,this.allowed=t}};export{t as n,e as t};
2
- //# sourceMappingURL=errors-CVBrIU1K.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-CVBrIU1K.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Domain errors for ContentClient + LockService.\n */\n\n/**\n * Thrown when a caller invokes an entity-capability-specific method on an\n * entity that doesn't have the corresponding behavior — e.g. `saveDraft`\n * on a non-publishable entity, `setLocaleStatus` on an entity without\n * publishable+translatable, `restoreVersion` on a non-versionable entity.\n *\n * Distinct from generic `Error` so admin-ui's API handler can map it to\n * 400 Bad Request (caller's fault) rather than 500 (server bug).\n */\nexport class EntityCapabilityError extends Error {\n readonly entityName: string\n readonly capability: 'drafts' | 'versions' | 'localeStatus' | 'translations'\n\n constructor(\n entityName: string,\n capability: EntityCapabilityError['capability'],\n message?: string,\n ) {\n super(\n message ??\n `Entity \"${entityName}\" does not support ${capability}. ` +\n `Add the corresponding behavior to defineEntity({ behaviors: [...] }).`,\n )\n this.name = 'EntityCapabilityError'\n this.entityName = entityName\n this.capability = capability\n }\n}\n\n/**\n * Thrown when a locale string passed at runtime is not configured in the\n * content plugin. The plugin validates `defaultLocale` at init time, but\n * the per-call `locale` parameter on every read/write is not naturally\n * checked — `validateLocale()` is the boundary check.\n *\n * Allows the `'_'` sentinel (used internally for default-locale rows in\n * versions/drafts/locale_status tables) so callers can pass it through.\n */\nexport class InvalidLocaleError extends Error {\n readonly locale: string\n readonly allowed: readonly string[]\n\n constructor(locale: string, allowed: readonly string[]) {\n super(\n `Invalid locale \"${locale}\". Configured locales: [${allowed.join(', ')}]. ` +\n `(The \"_\" sentinel is also accepted for default-locale storage.)`,\n )\n this.name = 'InvalidLocaleError'\n this.locale = locale\n this.allowed = allowed\n }\n}\n"],"mappings":"AAaA,IAAa,EAAb,cAA2C,KAAM,CAC/C,WACA,WAEA,YACE,EACA,EACA,EACA,CACA,MACE,GACE,WAAW,EAAW,qBAAqB,EAAW,yEAEzD,CACD,KAAK,KAAO,wBACZ,KAAK,WAAa,EAClB,KAAK,WAAa,IAaT,EAAb,cAAwC,KAAM,CAC5C,OACA,QAEA,YAAY,EAAgB,EAA4B,CACtD,MACE,mBAAmB,EAAO,0BAA0B,EAAQ,KAAK,KAAK,CAAC,oEAExE,CACD,KAAK,KAAO,qBACZ,KAAK,OAAS,EACd,KAAK,QAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CB0fdMs1.d.mts","names":[],"sources":["../src/behaviors/versionable.ts","../src/behaviors/with-overrides.ts","../src/behaviors/workflowable.ts","../src/capabilities.ts","../src/define-block.ts","../src/diff/types.ts","../src/errors.ts"],"mappings":";;;;KAmBY,iBAAA;EACV,QAAA,EAAU,WAAA;IAAgB,QAAA;EAAA;EAC1B,YAAA,EAAc,SAAA;AAAA;AAAA,iBAQA,WAAA,CAAY,OAAA,GAAU,kBAAA,GAAqB,QAAA,CAAS,iBAAA;;;;iBAqDpD,qBAAA,CAAsB,SAAA,GAAY,QAAA,KAAa,QAAA,CAAS,kBAAA;;;;ACrCV;;;;KAQzD,iBAAA;EACC,IAAA;AAAA;EAEA,IAAA;EACA,KAAA,GAAQ,MAAA;EACR,MAAA,GAAS,MAAA,SAAe,MAAA;AAAA;EAExB,IAAA;EAAiB,KAAA,EAAO,MAAA;AAAA;AAAA,KAEzB,YAAA,GAAe,MAAA,SAAe,iBAAA;AAAA,KAEvB,mBAAA;EAcV,UAAA,EAAY,SAAA;AAAA;;;;AAlBsB;iBAsLpB,aAAA,CAAA,GAAiB,QAAA,CAAS,mBAAA;;;;AAlL1C;;iBA8NgB,gBAAA,CACd,SAAA,EAAW,aAAA;EAAgB,IAAA;AAAA,IAAiB,MAAA;;;cCjPjC,eAAA;AAAA,KACD,aAAA,WAAwB,eAAA;;;;;;;;cASvB,oBAAA;EAAA;;;;;;;;;iBAWG,mBAAA,CAAoB,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,aAAA;;;;;cAUhD,uBAAA,SAAgC,KAAA;EAAA,SAClC,IAAA,EAAM,aAAA;EAAA,SACN,EAAA,EAAI,aAAA;cAED,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,aAAA;AAAA;AAAA,KAW3B,kBAAA;EACV,eAAA,EAAiB,WAAA;IAAgB,QAAA;EAAA;EACjC,iBAAA,EAAmB,SAAA;EACnB,aAAA,EAAe,SAAA;EACf,kBAAA,EAAoB,SAAA;AAAA;AAAA,iBAGN,YAAA,CAAA,GAAgB,QAAA,CAAS,kBAAA;;;KC7E7B,gBAAA;;;;;;iBAOI,cAAA,CAAe,MAAA,EAAQ,MAAA,EAAQ,UAAA,EAAY,gBAAA;;;iBCN3C,WAAA,iBAA4B,MAAA,SAAe,WAAA,EAAA,CAAc,UAAA;EACvE,IAAA;EACA,KAAA;EACA,MAAA,EAAQ,CAAA;AAAA,IACN,eAAA,CAAgB,CAAA;;;;;;;UCtBH,WAAA;EACf,IAAA;EACA,KAAA;AAAA;;UAIe,SAAA;EACf,KAAA;EACA,IAAA;EAWA,IAAA;EACA,EAAA;ELJuB;EKMvB,QAAA,GAAW,WAAA;ELEc;EKAzB,UAAA,GAAa,cAAA;AAAA;;KAIH,eAAA;;UAGK,cAAA;EACf,OAAA;EACA,SAAA;EACA,MAAA,EAAQ,eAAA;EACR,SAAA;EACA,OAAA;ELZmF;EKcnF,SAAA,GAAY,QAAA;AAAA;;UAIG,QAAA;EACf,KAAA;EACA,IAAA;EACA,EAAA;ELgCqE;EK9BrE,QAAA,GAAW,WAAA;AAAA;;;;;;;ALjCb;;;;;;;;cMNa,qBAAA,SAA8B,KAAA;EAAA,SAChC,UAAA;EAAA,SACA,UAAA;cAGP,UAAA,UACA,UAAA,EAAY,qBAAA,gBACZ,OAAA;AAAA;;;;;;;;;;cAsBS,kBAAA,SAA2B,KAAA;EAAA,SAC7B,MAAA;EAAA,SACA,OAAA;cAEG,MAAA,UAAgB,OAAA;AAAA"}
@@ -1,2 +0,0 @@
1
- import{n as e}from"./errors-CVBrIU1K.mjs";import{n as t}from"./plugin-DbK6FxTd.mjs";function n(n){if(n===`_`)return;let r=t();for(let e of r.locales)if(e.code===n)return;throw new e(n,r.locales.map(e=>e.code))}export{n as t};
2
- //# sourceMappingURL=locale-utils-DIcmuLIr.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale-utils-DIcmuLIr.mjs","names":[],"sources":["../src/locale-utils.ts"],"sourcesContent":["/**\n * Locale validation helpers.\n *\n * Every ContentClient and LockService method that accepts a `locale`\n * parameter must run it through `validateLocale()` before passing it to\n * the database. Drizzle parameterizes queries so SQL injection isn't a\n * concern, but unvalidated locale strings:\n * - bypass the configured locale set (typo'd `'frr'` writes a row that\n * never resolves on read),\n * - silently truncate at the column's `varchar(10)` boundary (e.g.\n * `'pt-BR-traditional'` → `'pt-BR-trad'`, breaking later equality),\n * - pollute drafts/versions/locale_status tables with rows that no\n * UI ever queries.\n *\n * The `'_'` sentinel is allowed because it's the conventional value for\n * default-locale rows in versions/drafts (where every row needs a\n * non-null `locale` for unique-constraint composition).\n */\n\nimport { InvalidLocaleError } from './errors.js'\nimport { getContentConfig } from './plugin.js'\n\n/** The internal sentinel for \"default locale\" used in version/draft storage. */\nexport const DEFAULT_LOCALE_SENTINEL = '_'\n\n/**\n * Throw `InvalidLocaleError` if `locale` is neither the `'_'` sentinel nor\n * one of the configured plugin locale codes.\n */\nexport function validateLocale(locale: string): void {\n if (locale === DEFAULT_LOCALE_SENTINEL) return\n const config = getContentConfig()\n for (const l of config.locales) {\n if (l.code === locale) return\n }\n throw new InvalidLocaleError(\n locale,\n config.locales.map((l) => l.code),\n )\n}\n"],"mappings":"oFA6BA,SAAgB,EAAe,EAAsB,CACnD,GAAI,IAAA,IAAoC,OACxC,IAAM,EAAS,GAAkB,CACjC,IAAK,IAAM,KAAK,EAAO,QACrB,GAAI,EAAE,OAAS,EAAQ,OAEzB,MAAM,IAAI,EACR,EACA,EAAO,QAAQ,IAAK,GAAM,EAAE,KAAK,CAClC"}
@@ -1,2 +0,0 @@
1
- import{n as e}from"./locks-BCHUb-yC.mjs";import{generateLayoutSchema as t,generateLayoutTranslationSchema as n}from"@murumets-ee/entity";import{definePlugin as r}from"@murumets-ee/core";import{column as i,defineTable as a,schemaRegistry as o}from"@murumets-ee/db";const s=new Map;function c(e,t){let n=s.get(e)??{};s.set(e,{...n,...t})}function l(e){return s.get(e)??{}}function u(e){return a({name:`${e.name}_drafts`,columns:{id:i.uuid({primaryKey:!0,defaultRandom:!0}),entityId:i.uuid({notNull:!0,pgName:`entity_id`}),locale:i.varchar({length:10,notNull:!0,default:`_`}),data:i.jsonb({notNull:!0}),createdBy:i.varchar({length:255,notNull:!0,pgName:`created_by`}),createdByName:i.varchar({length:255,pgName:`created_by_name`}),createdAt:i.timestamp({notNull:!0,defaultNow:!0,withTimezone:!0,pgName:`created_at`}),updatedAt:i.timestamp({notNull:!0,defaultNow:!0,withTimezone:!0,pgName:`updated_at`})},unique:[{on:[`entityId`,`locale`]}]})}function d(e){return a({name:`${e.name}_locale_status`,columns:{id:i.uuid({primaryKey:!0,defaultRandom:!0}),entityId:i.uuid({notNull:!0,pgName:`entity_id`}),locale:i.varchar({length:10,notNull:!0}),status:i.varchar({length:20,notNull:!0,default:`draft`}),publishedAt:i.timestamp({withTimezone:!0,pgName:`published_at`})},unique:[{on:[`entityId`,`locale`]}]})}function f(e){return a({name:`${e.name}_versions`,columns:{id:i.uuid({primaryKey:!0,defaultRandom:!0}),entityId:i.uuid({notNull:!0,pgName:`entity_id`}),version:i.integer({notNull:!0}),locale:i.varchar({length:10,notNull:!0,default:`_`}),data:i.jsonb({notNull:!0}),delta:i.jsonb(),status:i.varchar({length:20}),createdBy:i.varchar({length:255,pgName:`created_by`}),createdByName:i.varchar({length:255,pgName:`created_by_name`}),createdAt:i.timestamp({notNull:!0,defaultNow:!0,withTimezone:!0,pgName:`created_at`}),isAutosave:i.boolean({notNull:!0,default:!1,pgName:`is_autosave`})},unique:[{on:[`entityId`,`version`,`locale`]}]})}let p=null;function m(){if(!p)throw Error(`@murumets-ee/content plugin not initialized. Add content() to your plugins array.`);return p}function h(i){if(!i.locales||i.locales.length===0)throw Error(`content() requires at least one locale`);if(!i.defaultLocale)throw Error(`content() requires a defaultLocale`);if(!i.locales.some(e=>e.code===i.defaultLocale))throw Error(`defaultLocale "${i.defaultLocale}" not found in locales: [${i.locales.map(e=>e.code).join(`, `)}]`);return r({name:`@murumets-ee/content`,server:{tables:{toolkitContentLocks:e},init:async e=>{p=i;let r=0,a=0,s=0,l=0;for(let[i,p]of e.entities){if(p.behaviors?.some(e=>e.name===`versionable`)){let e=`${i}_versions`;if(!o.has(e)){let t=f(p);o.register(e,t.table),c(i,{versions:t})}r++}let e=p.allFields;if(Object.values(e).some(e=>e.type===`blocks`)){let e=`${i}_layout`;if(!o.has(e)){let n=t(p);n&&o.register(e,n)}let r=`${i}_layout_translations`;if(!o.has(r)){let e=n(p);e&&o.register(r,e)}a++}let m=p.behaviors?.some(e=>e.name===`publishable`),h=Object.values(e).some(e=>e.translatable);if(m&&h){let e=`${i}_locale_status`;if(!o.has(e)){let t=d(p);o.register(e,t.table),c(i,{localeStatus:t})}s++}if(m){let e=`${i}_drafts`;if(!o.has(e)){let t=u(p);o.register(e,t.table),c(i,{drafts:t})}l++}}e.logger.info({locales:i.locales.map(e=>e.code),defaultLocale:i.defaultLocale,versionableEntities:r,blockEntities:a,localeStatusEntities:s,draftEntities:l},`Content plugin initialized`)}}})}export{m as n,l as r,h as t};
2
- //# sourceMappingURL=plugin-DbK6FxTd.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-DbK6FxTd.mjs","names":[],"sources":["../src/schema/registry.ts","../src/schema/drafts.ts","../src/schema/locale-status.ts","../src/schema/versions.ts","../src/plugin.ts"],"sourcesContent":["/**\n * Per-entity content table registry.\n *\n * Maps an entity name to its content infrastructure tables — drafts,\n * versions, locale_status. Each entry stores the `DefinedTable` (from\n * `defineTable`), which exposes a typed `.makeClient(db)` for CRUD via\n * `TableClient` and a raw `.table` for legacy callers.\n *\n * The content plugin populates this registry at `init` time; ContentClient\n * reads from it lazily on first use. Tables that don't apply to an entity\n * (non-publishable entities have no drafts, etc.) are simply absent.\n */\n\nimport type { DraftsTable } from './drafts.js'\nimport type { LocaleStatusTable } from './locale-status.js'\nimport type { VersionsTable } from './versions.js'\n\n/**\n * The full set of optional content infra tables attached to an entity.\n * Every field is optional — entities without the relevant behavior don't\n * get the corresponding table.\n */\nexport interface ContentTables {\n /** `{entity}_drafts` — present when the entity has `publishable()`. */\n drafts?: DraftsTable\n /** `{entity}_versions` — present when the entity has `versionable()`. */\n versions?: VersionsTable\n /** `{entity}_locale_status` — present when the entity is publishable + has translatable fields. */\n localeStatus?: LocaleStatusTable\n}\n\n// Module-level map. Single source of truth for ContentClient lookups.\nconst tables = new Map<string, ContentTables>()\n\n/**\n * Register content tables for an entity. Called from `content().init()`.\n *\n * Subsequent calls for the same entity name MERGE the provided patch into\n * the existing entry. This lets the plugin add tables one at a time (drafts,\n * then versions, then locale_status) without the caller needing to build the\n * whole object up front.\n */\nexport function registerContentTables(entityName: string, patch: ContentTables): void {\n const existing = tables.get(entityName) ?? {}\n tables.set(entityName, { ...existing, ...patch })\n}\n\n/**\n * Get the content tables for an entity. Returns an empty object (rather\n * than undefined) when the entity has no registered tables — that\n * simplifies the common ContentClient lookup idiom:\n *\n * const { drafts } = getContentTables(entity.name)\n * if (!drafts) return null\n */\nexport function getContentTables(entityName: string): ContentTables {\n return tables.get(entityName) ?? {}\n}\n\n/**\n * Clear the registry. **Test-only.** Throws in production.\n */\nexport function clearContentTables(): void {\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'clearContentTables() is not allowed in production — this is a test-only utility.',\n )\n }\n tables.clear()\n}\n","/**\n * Draft overlay table schema generator\n *\n * Generates a {entity}_drafts table for entities with the publishable() behavior.\n * Stores a mutable work-in-progress snapshot that non-publishers edit instead of\n * writing directly to the live published row.\n *\n * One draft per entity+locale. Drafts are upserted, discarded, or promoted to live.\n *\n * Uses `defineTable` so ContentClient can operate on drafts through a typed\n * TableClient (see registry.ts). The migration pipeline uses the\n * entity-package generator (which emits FK references) — this one produces a\n * runtime-only table shape for read/write via TableClient.\n */\n\nimport { column, defineTable } from '@murumets-ee/db'\nimport type { Entity } from '@murumets-ee/entity'\n\n/**\n * Generate a `DefinedTable` for a publishable entity's drafts table.\n *\n * Schema:\n * {entity}_drafts (\n * id uuid PK,\n * entity_id uuid NOT NULL,\n * locale varchar(10) NOT NULL DEFAULT '_',\n * data jsonb NOT NULL, -- full entity snapshot\n * created_by varchar(255) NOT NULL, -- user ID (varchar, NOT uuid!)\n * created_by_name varchar(255),\n * created_at timestamptz NOT NULL DEFAULT now(),\n * updated_at timestamptz NOT NULL DEFAULT now(),\n * UNIQUE(entity_id, locale)\n * )\n */\nexport function generateDraftsTable(entity: Entity) {\n return defineTable({\n name: `${entity.name}_drafts`,\n columns: {\n id: column.uuid({ primaryKey: true, defaultRandom: true }),\n entityId: column.uuid({ notNull: true, pgName: 'entity_id' }),\n locale: column.varchar({ length: 10, notNull: true, default: '_' }),\n data: column.jsonb<Record<string, unknown>, true>({ notNull: true }),\n createdBy: column.varchar({ length: 255, notNull: true, pgName: 'created_by' }),\n createdByName: column.varchar({ length: 255, pgName: 'created_by_name' }),\n createdAt: column.timestamp({\n notNull: true,\n defaultNow: true,\n withTimezone: true,\n pgName: 'created_at',\n }),\n updatedAt: column.timestamp({\n notNull: true,\n defaultNow: true,\n withTimezone: true,\n pgName: 'updated_at',\n }),\n },\n unique: [{ on: ['entityId', 'locale'] }],\n })\n}\n\n/** Public type export — the full DefinedTable returned by the generator. */\nexport type DraftsTable = ReturnType<typeof generateDraftsTable>\n","/**\n * Per-locale publish status table schema generator\n *\n * Generates a {entity}_locale_status table for entities that have both\n * publishable() behavior AND translatable fields. This allows different\n * locales to have independent publish statuses.\n *\n * Fallback rule: no row for a locale = inherit base entity status.\n *\n * Uses `defineTable` so ContentClient can operate on rows through a typed\n * TableClient. The migration pipeline uses the entity-package generator\n * (which emits FK references); this one produces a runtime-only table shape\n * for read/write via TableClient.\n */\n\nimport { column, defineTable } from '@murumets-ee/db'\nimport type { Entity } from '@murumets-ee/entity'\n\n/**\n * Generate a `DefinedTable` for a publishable + translatable entity's\n * locale status table.\n *\n * Schema:\n * {entity}_locale_status (\n * id uuid PK,\n * entity_id uuid NOT NULL,\n * locale varchar(10) NOT NULL,\n * status varchar(20) NOT NULL DEFAULT 'draft',\n * published_at timestamptz,\n * UNIQUE(entity_id, locale)\n * )\n */\nexport function generateLocaleStatusTable(entity: Entity) {\n return defineTable({\n name: `${entity.name}_locale_status`,\n columns: {\n id: column.uuid({ primaryKey: true, defaultRandom: true }),\n entityId: column.uuid({ notNull: true, pgName: 'entity_id' }),\n locale: column.varchar({ length: 10, notNull: true }),\n status: column.varchar({ length: 20, notNull: true, default: 'draft' }),\n publishedAt: column.timestamp({ withTimezone: true, pgName: 'published_at' }),\n },\n unique: [{ on: ['entityId', 'locale'] }],\n })\n}\n\n/** Public type export — the full DefinedTable returned by the generator. */\nexport type LocaleStatusTable = ReturnType<typeof generateLocaleStatusTable>\n","/**\n * Version history table schema generator\n *\n * Generates a {entity}_versions table for entities with the versionable() behavior.\n * Each version stores a full snapshot + delta (changed fields only).\n *\n * Uses `defineTable` so ContentClient can operate on versions through a typed\n * TableClient. The migration pipeline uses the entity-package generator\n * (which emits FK references) — this one produces a runtime-only table shape\n * for read/write via TableClient.\n */\n\nimport { column, defineTable } from '@murumets-ee/db'\nimport type { Entity } from '@murumets-ee/entity'\n\n/**\n * Generate a `DefinedTable` for a versionable entity's versions table.\n *\n * Schema:\n * {entity}_versions (\n * id uuid PK,\n * entity_id uuid NOT NULL,\n * version integer NOT NULL,\n * locale varchar(10) NOT NULL DEFAULT '_', -- locale this snapshot belongs to\n * data jsonb NOT NULL, -- full snapshot (locale-merged view)\n * delta jsonb, -- only changed fields\n * status varchar(20), -- 'draft' | 'published' at time of save\n * created_by varchar(255),\n * created_by_name varchar(255),\n * created_at timestamptz NOT NULL DEFAULT now(),\n * is_autosave boolean NOT NULL DEFAULT false,\n * UNIQUE(entity_id, version, locale)\n * )\n *\n * Each locale has its own version sequence. The default locale uses '_'\n * as the locale value (distinguishable from actual locale codes).\n */\nexport function generateVersionsTable(entity: Entity) {\n return defineTable({\n name: `${entity.name}_versions`,\n columns: {\n id: column.uuid({ primaryKey: true, defaultRandom: true }),\n entityId: column.uuid({ notNull: true, pgName: 'entity_id' }),\n version: column.integer({ notNull: true }),\n locale: column.varchar({ length: 10, notNull: true, default: '_' }),\n data: column.jsonb<Record<string, unknown>, true>({ notNull: true }),\n delta: column.jsonb<Record<string, unknown>>(),\n status: column.varchar({ length: 20 }),\n createdBy: column.varchar({ length: 255, pgName: 'created_by' }),\n createdByName: column.varchar({ length: 255, pgName: 'created_by_name' }),\n createdAt: column.timestamp({\n notNull: true,\n defaultNow: true,\n withTimezone: true,\n pgName: 'created_at',\n }),\n isAutosave: column.boolean({ notNull: true, default: false, pgName: 'is_autosave' }),\n },\n unique: [{ on: ['entityId', 'version', 'locale'] }],\n })\n}\n\n/** Public type export — the full DefinedTable returned by the generator. */\nexport type VersionsTable = ReturnType<typeof generateVersionsTable>\n","/**\n * Content plugin — registers locale configuration and version schemas.\n *\n * Usage:\n * import { content } from '@murumets-ee/content/plugin'\n *\n * export default defineLumiConfig({\n * plugins: [\n * content({\n * locales: [\n * { code: 'en', label: 'English' },\n * { code: 'de', label: 'German' },\n * ],\n * defaultLocale: 'en',\n * }),\n * ],\n * })\n */\n\nimport { definePlugin } from '@murumets-ee/core'\nimport { schemaRegistry } from '@murumets-ee/db'\nimport { generateLayoutSchema, generateLayoutTranslationSchema } from '@murumets-ee/entity'\nimport { generateDraftsTable } from './schema/drafts.js'\nimport { generateLocaleStatusTable } from './schema/locale-status.js'\nimport { toolkitContentLocks } from './schema/locks.js'\nimport { registerContentTables } from './schema/registry.js'\nimport { generateVersionsTable } from './schema/versions.js'\nimport type { ContentConfig } from './types.js'\n\nlet _contentConfig: ContentConfig | null = null\n\n/**\n * Get the content configuration. Throws if plugin not initialized.\n */\nexport function getContentConfig(): ContentConfig {\n if (!_contentConfig) {\n throw new Error(\n '@murumets-ee/content plugin not initialized. Add content() to your plugins array.',\n )\n }\n return _contentConfig\n}\n\n/**\n * Content plugin factory.\n */\nexport function content(config: ContentConfig) {\n // Validate config\n if (!config.locales || config.locales.length === 0) {\n throw new Error('content() requires at least one locale')\n }\n\n if (!config.defaultLocale) {\n throw new Error('content() requires a defaultLocale')\n }\n\n const defaultExists = config.locales.some((l) => l.code === config.defaultLocale)\n if (!defaultExists) {\n throw new Error(\n `defaultLocale \"${config.defaultLocale}\" not found in locales: [${config.locales.map((l) => l.code).join(', ')}]`,\n )\n }\n\n return definePlugin({\n name: '@murumets-ee/content',\n server: {\n // The shared locks table is registered declaratively via the\n // framework's merge step (#469). The per-entity tables below\n // (versions / layout / drafts / locale_status) are generated\n // dynamically from `app.entities` and stay imperatively\n // registered — they're not known at plugin-construct time.\n tables: { toolkitContentLocks },\n init: async (app) => {\n // Store config globally\n _contentConfig = config\n\n let versionableCount = 0\n let blocksCount = 0\n let localeStatusCount = 0\n let draftsCount = 0\n\n for (const [name, entity] of app.entities) {\n // Register version tables for versionable entities\n const hasVersionable = entity.behaviors?.some(\n (b: { name: string }) => b.name === 'versionable',\n )\n if (hasVersionable) {\n const versionsTableName = `${name}_versions`\n if (!schemaRegistry.has(versionsTableName)) {\n const versions = generateVersionsTable(entity)\n schemaRegistry.register(versionsTableName, versions.table)\n registerContentTables(name, { versions })\n }\n versionableCount++\n }\n\n // Register layout tables for entities with blocks fields\n const allFields = entity.allFields as Record<\n string,\n { type: string; translatable?: boolean }\n >\n const hasBlocks = Object.values(allFields).some((f) => f.type === 'blocks')\n if (hasBlocks) {\n const layoutTableName = `${name}_layout`\n if (!schemaRegistry.has(layoutTableName)) {\n const layoutSchema = generateLayoutSchema(entity)\n if (layoutSchema) {\n schemaRegistry.register(layoutTableName, layoutSchema)\n }\n }\n\n const layoutTransTableName = `${name}_layout_translations`\n if (!schemaRegistry.has(layoutTransTableName)) {\n const layoutTransSchema = generateLayoutTranslationSchema(entity)\n if (layoutTransSchema) {\n schemaRegistry.register(layoutTransTableName, layoutTransSchema)\n }\n }\n\n blocksCount++\n }\n\n // Register locale_status tables for publishable + translatable entities\n const isPublishable = entity.behaviors?.some(\n (b: { name: string }) => b.name === 'publishable',\n )\n const hasTranslatable = Object.values(allFields).some((f) => f.translatable)\n if (isPublishable && hasTranslatable) {\n const statusTableName = `${name}_locale_status`\n if (!schemaRegistry.has(statusTableName)) {\n const localeStatus = generateLocaleStatusTable(entity)\n schemaRegistry.register(statusTableName, localeStatus.table)\n registerContentTables(name, { localeStatus })\n }\n localeStatusCount++\n }\n\n // Register drafts table for publishable entities\n if (isPublishable) {\n const draftsTableName = `${name}_drafts`\n if (!schemaRegistry.has(draftsTableName)) {\n const drafts = generateDraftsTable(entity)\n schemaRegistry.register(draftsTableName, drafts.table)\n registerContentTables(name, { drafts })\n }\n draftsCount++\n }\n }\n\n app.logger.info(\n {\n locales: config.locales.map((l) => l.code),\n defaultLocale: config.defaultLocale,\n versionableEntities: versionableCount,\n blockEntities: blocksCount,\n localeStatusEntities: localeStatusCount,\n draftEntities: draftsCount,\n },\n 'Content plugin initialized',\n )\n },\n },\n })\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-CWo2dfEK.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;UAeiB,eAAA,WACL,MAAA,SAAe,WAAA,IAAe,MAAA,SAAe,WAAA;EAEvD,IAAA;EACA,KAAA;EACA,MAAA,EAAQ,CAAA;AAAA;;;;;KAWE,cAAA,WAAyB,eAAA,IACnC,CAAA,SAAU,eAAA;EACJ,MAAA,EAAQ,CAAA;EAAW,GAAA;AAAA,IAAgB,IAAA,CAAK,cAAA,CAAe,CAAA;;;AAF/D;;;;;KAYY,gBAAA,oBAAoC,eAAA,oBAClC,CAAA,GAAI,CAAA,CAAE,CAAA,UAAW,eAAA,GAAkB,cAAA,CAAe,CAAA,CAAE,CAAA;AAAA,UAOjD,YAAA;EACf,IAAA;EACA,KAAA;AAAA;AAAA,UAGe,aAAA;EACf,OAAA,EAAS,YAAA;EACT,aAAA;AAAA;AAAA,UAOe,kBAAA;EAhCT;EAkCN,SAAA;EAlCyB;EAoCzB,QAAA;AAAA;AAAA,UAOe,YAAA,eAA2B,MAAA,oBAA0B,MAAA;EACpE,EAAA;EACA,QAAA;EACA,OAAA;EACA,MAAA;EACA,IAAA,EAAM,KAAA;EACN,KAAA,EAAO,OAAA,CAAQ,KAAA;EACf,MAAA;EACA,SAAA;EACA,aAAA;EACA,SAAA,EAAW,IAAA;EACX,UAAA;AAAA;AAAA,UAae,sBAAA;EACf,QAAA;EACA,KAAA;EACA,UAAA;EACA,OAAA;AAAA;AAAA,UAGe,iBAAA;EAAA,CACd,MAAA,WAAiB,sBAAA;AAAA;AAAA,UAGH,iBAAA;EACf,KAAA;EACA,QAAA;EACA,OAAA;EACA,OAAA;AAAA;AAAA,UAOe,mBAAA;EACf,MAAA;EACA,MAAA;EACA,WAAA,EAAa,IAAA;AAAA;AAAA,UAOE,UAAA,eAAyB,MAAA,oBAA0B,MAAA;EAClE,EAAA;EACA,QAAA;EACA,MAAA;EACA,IAAA,EAAM,KAAA;EACN,SAAA;EACA,aAAA;EACA,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;AAAA;AAAA,UAOI,QAAA;EACf,QAAA;EACA,YAAA;EACA,QAAA,EAAU,IAAA;EACV,SAAA,EAAW,IAAA;AAAA"}