@beechcms/core 0.9.0 → 0.9.2

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 (203) hide show
  1. package/dist/dashboard-layout/content-view.d.ts +4 -4
  2. package/package.json +2 -2
  3. package/dist/automations-grammar-words.d.ts +0 -2
  4. package/dist/automations-grammar-words.d.ts.map +0 -1
  5. package/dist/automations-grammar-words.js +0 -8
  6. package/dist/automations.repository.interface.d.ts +0 -19
  7. package/dist/automations.repository.interface.d.ts.map +0 -1
  8. package/dist/automations.repository.interface.js +0 -3
  9. package/dist/automations.runner.interface.d.ts +0 -10
  10. package/dist/automations.runner.interface.d.ts.map +0 -1
  11. package/dist/automations.runner.interface.js +0 -3
  12. package/dist/automations.runner.stub.d.ts +0 -5
  13. package/dist/automations.runner.stub.d.ts.map +0 -1
  14. package/dist/automations.runner.stub.js +0 -7
  15. package/dist/automations.types.d.ts +0 -75
  16. package/dist/automations.types.d.ts.map +0 -1
  17. package/dist/automations.types.js +0 -3
  18. package/dist/clock.d.ts +0 -25
  19. package/dist/clock.d.ts.map +0 -1
  20. package/dist/clock.js +0 -11
  21. package/dist/content-scan.repository.d.ts +0 -9
  22. package/dist/content-scan.repository.d.ts.map +0 -1
  23. package/dist/content-scan.repository.js +0 -3
  24. package/dist/content.repository.d.ts +0 -247
  25. package/dist/content.repository.d.ts.map +0 -1
  26. package/dist/content.repository.js +0 -59
  27. package/dist/dashboard-layout/kanban/kanban-position.repository.d.ts +0 -19
  28. package/dist/dashboard-layout/kanban/kanban-position.repository.d.ts.map +0 -1
  29. package/dist/dashboard-layout/kanban/kanban-position.repository.js +0 -3
  30. package/dist/dashboard-layout.d.ts +0 -154
  31. package/dist/dashboard-layout.d.ts.map +0 -1
  32. package/dist/dashboard-layout.js +0 -186
  33. package/dist/dashboard-layout.repository.d.ts +0 -18
  34. package/dist/dashboard-layout.repository.d.ts.map +0 -1
  35. package/dist/dashboard-layout.repository.js +0 -3
  36. package/dist/dashboard-permissions.d.ts +0 -3
  37. package/dist/dashboard-permissions.d.ts.map +0 -1
  38. package/dist/dashboard-permissions.js +0 -11
  39. package/dist/dashboard-scopes.d.ts +0 -12
  40. package/dist/dashboard-scopes.d.ts.map +0 -1
  41. package/dist/dashboard-scopes.js +0 -30
  42. package/dist/define-seed.d.ts +0 -3
  43. package/dist/define-seed.d.ts.map +0 -1
  44. package/dist/define-seed.js +0 -5
  45. package/dist/demo-data.repository.d.ts +0 -5
  46. package/dist/demo-data.repository.d.ts.map +0 -1
  47. package/dist/demo-data.repository.js +0 -3
  48. package/dist/email.provider.d.ts +0 -32
  49. package/dist/email.provider.d.ts.map +0 -1
  50. package/dist/email.provider.js +0 -4
  51. package/dist/engine/ddl/seed-ddl-destructive.d.ts +0 -40
  52. package/dist/engine/ddl/seed-ddl-destructive.d.ts.map +0 -1
  53. package/dist/engine/ddl/seed-ddl-destructive.js +0 -149
  54. package/dist/engine/ddl.d.ts +0 -193
  55. package/dist/engine/ddl.d.ts.map +0 -1
  56. package/dist/engine/ddl.js +0 -518
  57. package/dist/engine/define-seed.d.ts +0 -3
  58. package/dist/engine/define-seed.d.ts.map +0 -1
  59. package/dist/engine/define-seed.js +0 -5
  60. package/dist/engine/introspection.d.ts +0 -101
  61. package/dist/engine/introspection.d.ts.map +0 -1
  62. package/dist/engine/introspection.js +0 -127
  63. package/dist/engine/localization.d.ts +0 -127
  64. package/dist/engine/localization.d.ts.map +0 -1
  65. package/dist/engine/localization.js +0 -212
  66. package/dist/engine/policies.d.ts +0 -58
  67. package/dist/engine/policies.d.ts.map +0 -1
  68. package/dist/engine/policies.js +0 -168
  69. package/dist/engine/privacy.service.d.ts +0 -65
  70. package/dist/engine/privacy.service.d.ts.map +0 -1
  71. package/dist/engine/privacy.service.js +0 -114
  72. package/dist/engine/query.d.ts +0 -23
  73. package/dist/engine/query.d.ts.map +0 -1
  74. package/dist/engine/query.js +0 -236
  75. package/dist/engine/relations.d.ts +0 -28
  76. package/dist/engine/relations.d.ts.map +0 -1
  77. package/dist/engine/relations.js +0 -25
  78. package/dist/engine/schema-fingerprint.d.ts +0 -73
  79. package/dist/engine/schema-fingerprint.d.ts.map +0 -1
  80. package/dist/engine/schema-fingerprint.js +0 -97
  81. package/dist/engine/schema-mutator.d.ts +0 -26
  82. package/dist/engine/schema-mutator.d.ts.map +0 -1
  83. package/dist/engine/schema-mutator.js +0 -3
  84. package/dist/engine/seed-ddl-destructive.d.ts +0 -40
  85. package/dist/engine/seed-ddl-destructive.d.ts.map +0 -1
  86. package/dist/engine/seed-ddl-destructive.js +0 -149
  87. package/dist/engine/seed-ddl.d.ts +0 -40
  88. package/dist/engine/seed-ddl.d.ts.map +0 -1
  89. package/dist/engine/seed-ddl.js +0 -100
  90. package/dist/engine/seed-registry.d.ts +0 -71
  91. package/dist/engine/seed-registry.d.ts.map +0 -1
  92. package/dist/engine/seed-registry.js +0 -167
  93. package/dist/engine/seed-types-generator.d.ts +0 -10
  94. package/dist/engine/seed-types-generator.d.ts.map +0 -1
  95. package/dist/engine/seed-types-generator.js +0 -89
  96. package/dist/engine/seed-validation.d.ts +0 -30
  97. package/dist/engine/seed-validation.d.ts.map +0 -1
  98. package/dist/engine/seed-validation.js +0 -319
  99. package/dist/engine/seeds.d.ts +0 -20
  100. package/dist/engine/seeds.d.ts.map +0 -1
  101. package/dist/engine/seeds.js +0 -21
  102. package/dist/engine/serialize.d.ts +0 -20
  103. package/dist/engine/serialize.d.ts.map +0 -1
  104. package/dist/engine/serialize.js +0 -160
  105. package/dist/engine.d.ts +0 -144
  106. package/dist/engine.d.ts.map +0 -1
  107. package/dist/engine.js +0 -741
  108. package/dist/file-types.d.ts +0 -13
  109. package/dist/file-types.d.ts.map +0 -1
  110. package/dist/file-types.js +0 -85
  111. package/dist/hooks.d.ts +0 -29
  112. package/dist/hooks.d.ts.map +0 -1
  113. package/dist/hooks.js +0 -3
  114. package/dist/id-generator.d.ts +0 -26
  115. package/dist/id-generator.d.ts.map +0 -1
  116. package/dist/id-generator.js +0 -12
  117. package/dist/idempotency.repository.d.ts +0 -13
  118. package/dist/idempotency.repository.d.ts.map +0 -1
  119. package/dist/idempotency.repository.js +0 -3
  120. package/dist/kanban-position.repository.d.ts +0 -19
  121. package/dist/kanban-position.repository.d.ts.map +0 -1
  122. package/dist/kanban-position.repository.js +0 -3
  123. package/dist/kanban.d.ts +0 -75
  124. package/dist/kanban.d.ts.map +0 -1
  125. package/dist/kanban.js +0 -82
  126. package/dist/layout-permissions.d.ts +0 -3
  127. package/dist/layout-permissions.d.ts.map +0 -1
  128. package/dist/layout-permissions.js +0 -11
  129. package/dist/media.repository.d.ts +0 -61
  130. package/dist/media.repository.d.ts.map +0 -1
  131. package/dist/media.repository.js +0 -3
  132. package/dist/policies.d.ts +0 -10
  133. package/dist/policies.d.ts.map +0 -1
  134. package/dist/policies.js +0 -33
  135. package/dist/queue.interface.d.ts +0 -39
  136. package/dist/queue.interface.d.ts.map +0 -1
  137. package/dist/queue.interface.js +0 -3
  138. package/dist/queue.stub.d.ts +0 -6
  139. package/dist/queue.stub.d.ts.map +0 -1
  140. package/dist/queue.stub.js +0 -8
  141. package/dist/relations.d.ts +0 -28
  142. package/dist/relations.d.ts.map +0 -1
  143. package/dist/relations.js +0 -25
  144. package/dist/richtext-render.d.ts +0 -11
  145. package/dist/richtext-render.d.ts.map +0 -1
  146. package/dist/richtext-render.js +0 -87
  147. package/dist/richtext.d.ts +0 -11
  148. package/dist/richtext.d.ts.map +0 -1
  149. package/dist/richtext.js +0 -13
  150. package/dist/scheduler.interface.d.ts +0 -4
  151. package/dist/scheduler.interface.d.ts.map +0 -1
  152. package/dist/scheduler.interface.js +0 -3
  153. package/dist/scheduler.stub.d.ts +0 -5
  154. package/dist/scheduler.stub.d.ts.map +0 -1
  155. package/dist/scheduler.stub.js +0 -7
  156. package/dist/schema-mutator.d.ts +0 -26
  157. package/dist/schema-mutator.d.ts.map +0 -1
  158. package/dist/schema-mutator.js +0 -3
  159. package/dist/seed-ddl-destructive.d.ts +0 -40
  160. package/dist/seed-ddl-destructive.d.ts.map +0 -1
  161. package/dist/seed-ddl-destructive.js +0 -149
  162. package/dist/seed-ddl.d.ts +0 -40
  163. package/dist/seed-ddl.d.ts.map +0 -1
  164. package/dist/seed-ddl.js +0 -100
  165. package/dist/seed-layout.d.ts +0 -145
  166. package/dist/seed-layout.d.ts.map +0 -1
  167. package/dist/seed-layout.js +0 -192
  168. package/dist/seed-layout.repository.d.ts +0 -22
  169. package/dist/seed-layout.repository.d.ts.map +0 -1
  170. package/dist/seed-layout.repository.js +0 -3
  171. package/dist/seed-registry.d.ts +0 -71
  172. package/dist/seed-registry.d.ts.map +0 -1
  173. package/dist/seed-registry.js +0 -143
  174. package/dist/seed-types-generator.d.ts +0 -10
  175. package/dist/seed-types-generator.d.ts.map +0 -1
  176. package/dist/seed-types-generator.js +0 -86
  177. package/dist/seed-validation.d.ts +0 -23
  178. package/dist/seed-validation.d.ts.map +0 -1
  179. package/dist/seed-validation.js +0 -224
  180. package/dist/seed.repository.d.ts +0 -37
  181. package/dist/seed.repository.d.ts.map +0 -1
  182. package/dist/seed.repository.js +0 -3
  183. package/dist/seeds.d.ts +0 -20
  184. package/dist/seeds.d.ts.map +0 -1
  185. package/dist/seeds.js +0 -21
  186. package/dist/site-settings.repository.d.ts +0 -16
  187. package/dist/site-settings.repository.d.ts.map +0 -1
  188. package/dist/site-settings.repository.js +0 -3
  189. package/dist/slug-utils.d.ts +0 -18
  190. package/dist/slug-utils.d.ts.map +0 -1
  191. package/dist/slug-utils.js +0 -32
  192. package/dist/storage.d.ts +0 -46
  193. package/dist/storage.d.ts.map +0 -1
  194. package/dist/storage.js +0 -3
  195. package/dist/types.d.ts +0 -243
  196. package/dist/types.d.ts.map +0 -1
  197. package/dist/types.js +0 -3
  198. package/dist/validation.d.ts +0 -50
  199. package/dist/validation.d.ts.map +0 -1
  200. package/dist/validation.js +0 -660
  201. package/dist/webhook-validation.d.ts +0 -3
  202. package/dist/webhook-validation.d.ts.map +0 -1
  203. package/dist/webhook-validation.js +0 -6
@@ -1,154 +0,0 @@
1
- import { z } from 'zod';
2
- import type { Seed } from './types.js';
3
- /** A placed widget. `type` is namespaced ('core/stat', '@acme/weather').
4
- * `config` is opaque to core/API except for the optional `seedSlug` key,
5
- * which enables auto-cleanup when the referenced seed disappears. */
6
- export interface DashboardWidgetInstance {
7
- id: string;
8
- type: string;
9
- title?: string;
10
- config: Record<string, unknown>;
11
- }
12
- export interface DashboardColumn {
13
- id: string;
14
- widgets: DashboardWidgetInstance[];
15
- }
16
- export interface DashboardSection {
17
- id: string;
18
- label?: string;
19
- hideLabel?: boolean;
20
- collapsible?: boolean;
21
- /** 1–4 columns. Enforced by validator. */
22
- columns: DashboardColumn[];
23
- /** Optional spans on a 12-unit grid, parallel to `columns`, must sum to 12.
24
- * Absent = equal split. */
25
- columnSpans?: number[];
26
- }
27
- export interface DashboardPageLayout {
28
- id: string;
29
- /** URL identity (?page=<slug>). Unique within the layout. */
30
- slug: string;
31
- label: string;
32
- /** Lucide icon name, same convention as DashboardSeedConfig.icon. */
33
- icon?: string;
34
- sections: DashboardSection[];
35
- }
36
- export interface DashboardLayout {
37
- /** Format version — bump when introducing breaking changes. */
38
- version: 1;
39
- pages: DashboardPageLayout[];
40
- }
41
- /** Namespaced widget type — lowercase npm-name-compatible.
42
- * Built-ins use the 'core/' prefix; custom widgets '@scope/name'. */
43
- export declare const WIDGET_TYPE_REGEX: RegExp;
44
- /** Max serialized size of a single widget `config`
45
- * (`JSON.stringify(widget.config).length`) — guards D1 row bloat. */
46
- export declare const MAX_WIDGET_CONFIG_BYTES = 8192;
47
- export declare const dashboardWidgetInstanceSchema: z.ZodObject<{
48
- id: z.ZodString;
49
- type: z.ZodString;
50
- title: z.ZodOptional<z.ZodString>;
51
- config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
52
- }, z.core.$strip>;
53
- export declare const dashboardColumnSchema: z.ZodObject<{
54
- id: z.ZodString;
55
- widgets: z.ZodArray<z.ZodObject<{
56
- id: z.ZodString;
57
- type: z.ZodString;
58
- title: z.ZodOptional<z.ZodString>;
59
- config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
60
- }, z.core.$strip>>;
61
- }, z.core.$strip>;
62
- export declare const dashboardSectionSchema: z.ZodObject<{
63
- id: z.ZodString;
64
- label: z.ZodOptional<z.ZodString>;
65
- hideLabel: z.ZodOptional<z.ZodBoolean>;
66
- collapsible: z.ZodOptional<z.ZodBoolean>;
67
- columns: z.ZodArray<z.ZodObject<{
68
- id: z.ZodString;
69
- widgets: z.ZodArray<z.ZodObject<{
70
- id: z.ZodString;
71
- type: z.ZodString;
72
- title: z.ZodOptional<z.ZodString>;
73
- config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
74
- }, z.core.$strip>>;
75
- }, z.core.$strip>>;
76
- columnSpans: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
77
- }, z.core.$strip>;
78
- export declare const dashboardPageSchema: z.ZodObject<{
79
- id: z.ZodString;
80
- slug: z.ZodString;
81
- label: z.ZodString;
82
- icon: z.ZodOptional<z.ZodString>;
83
- sections: z.ZodArray<z.ZodObject<{
84
- id: z.ZodString;
85
- label: z.ZodOptional<z.ZodString>;
86
- hideLabel: z.ZodOptional<z.ZodBoolean>;
87
- collapsible: z.ZodOptional<z.ZodBoolean>;
88
- columns: z.ZodArray<z.ZodObject<{
89
- id: z.ZodString;
90
- widgets: z.ZodArray<z.ZodObject<{
91
- id: z.ZodString;
92
- type: z.ZodString;
93
- title: z.ZodOptional<z.ZodString>;
94
- config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
95
- }, z.core.$strip>>;
96
- }, z.core.$strip>>;
97
- columnSpans: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
98
- }, z.core.$strip>>;
99
- }, z.core.$strip>;
100
- export declare const dashboardLayoutSchema: z.ZodObject<{
101
- version: z.ZodLiteral<1>;
102
- pages: z.ZodArray<z.ZodObject<{
103
- id: z.ZodString;
104
- slug: z.ZodString;
105
- label: z.ZodString;
106
- icon: z.ZodOptional<z.ZodString>;
107
- sections: z.ZodArray<z.ZodObject<{
108
- id: z.ZodString;
109
- label: z.ZodOptional<z.ZodString>;
110
- hideLabel: z.ZodOptional<z.ZodBoolean>;
111
- collapsible: z.ZodOptional<z.ZodBoolean>;
112
- columns: z.ZodArray<z.ZodObject<{
113
- id: z.ZodString;
114
- widgets: z.ZodArray<z.ZodObject<{
115
- id: z.ZodString;
116
- type: z.ZodString;
117
- title: z.ZodOptional<z.ZodString>;
118
- config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
119
- }, z.core.$strip>>;
120
- }, z.core.$strip>>;
121
- columnSpans: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
122
- }, z.core.$strip>>;
123
- }, z.core.$strip>>;
124
- }, z.core.$strip>;
125
- /** Structural port of the legacy hardcoded dashboard config into a single
126
- * 'Overview' page. Widgets fetch their own data: configs carry only the
127
- * variant and (where relevant) the default seed binding. */
128
- export declare function generateDefaultDashboardLayout(seeds: Seed[], opts?: {
129
- newId: () => string;
130
- }): DashboardLayout;
131
- export interface DashboardLayoutContext {
132
- /** Slugs of currently registered seeds (from ISeedRegistry.all()). */
133
- seedSlugs: ReadonlySet<string>;
134
- /** Optional: widget types known to the caller (frontend registry).
135
- * When provided, unknown types produce WARNINGS, never strips. */
136
- knownWidgetTypes?: ReadonlySet<string>;
137
- }
138
- export type ValidateDashboardLayoutResult = {
139
- ok: true;
140
- cleaned: DashboardLayout;
141
- warnings: string[];
142
- } | {
143
- ok: false;
144
- errors: string[];
145
- cleaned: DashboardLayout;
146
- warnings: string[];
147
- };
148
- /** Semantic validation on top of the Zod shape check (the caller's job).
149
- * Widgets bound to a seed that no longer exists are silently stripped
150
- * (auto-cleanup, recorded as a warning). Unknown widget types only warn —
151
- * custom widgets are invisible to the Worker and must never be stripped.
152
- * `cleaned` is always returned, errors or not. */
153
- export declare function validateDashboardLayout(layout: DashboardLayout, ctx: DashboardLayoutContext): ValidateDashboardLayoutResult;
154
- //# sourceMappingURL=dashboard-layout.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-layout.d.ts","sourceRoot":"","sources":["../src/dashboard-layout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAMtC;;sEAEsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,uBAAuB,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B;gCAC4B;IAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,OAAO,EAAE,CAAC,CAAA;IACV,KAAK,EAAE,mBAAmB,EAAE,CAAA;CAC7B;AAMD;sEACsE;AACtE,eAAO,MAAM,iBAAiB,QAA6B,CAAA;AAE3D;sEACsE;AACtE,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAM3C,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAA;AACF,eAAO,MAAM,qBAAqB;;;;;;;;iBAGhC,CAAA;AACF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;iBAOjC,CAAA;AACF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;iBAM9B,CAAA;AACF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;iBAGhC,CAAA;AAQF;;6DAE6D;AAC7D,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,MAAM,CAAA;CAAE,GAC7B,eAAe,CA2EjB;AAMD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC9B;uEACmE;IACnE,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACvC;AAED,MAAM,MAAM,6BAA6B,GACrC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAC1D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAEjF;;;;mDAImD;AACnD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,sBAAsB,GAC1B,6BAA6B,CA2E/B"}
@@ -1,186 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- import { z } from 'zod';
4
- // ---------------------------------------------------------------------------
5
- // Shared rules used by both the Zod schemas and the semantic validator.
6
- // ---------------------------------------------------------------------------
7
- /** Namespaced widget type — lowercase npm-name-compatible.
8
- * Built-ins use the 'core/' prefix; custom widgets '@scope/name'. */
9
- export const WIDGET_TYPE_REGEX = /^[a-z0-9@][a-z0-9@/_-]*$/;
10
- /** Max serialized size of a single widget `config`
11
- * (`JSON.stringify(widget.config).length`) — guards D1 row bloat. */
12
- export const MAX_WIDGET_CONFIG_BYTES = 8192;
13
- // ---------------------------------------------------------------------------
14
- // Zod schemas for shape validation
15
- // ---------------------------------------------------------------------------
16
- export const dashboardWidgetInstanceSchema = z.object({
17
- id: z.string().min(1),
18
- type: z.string().regex(WIDGET_TYPE_REGEX),
19
- title: z.string().max(80).optional(),
20
- config: z.record(z.string(), z.unknown()),
21
- });
22
- export const dashboardColumnSchema = z.object({
23
- id: z.string().min(1),
24
- widgets: z.array(dashboardWidgetInstanceSchema),
25
- });
26
- export const dashboardSectionSchema = z.object({
27
- id: z.string().min(1),
28
- label: z.string().max(60).optional(),
29
- hideLabel: z.boolean().optional(),
30
- collapsible: z.boolean().optional(),
31
- columns: z.array(dashboardColumnSchema).min(1).max(4),
32
- columnSpans: z.array(z.number().int().min(1).max(12)).optional(),
33
- });
34
- export const dashboardPageSchema = z.object({
35
- id: z.string().min(1),
36
- slug: z.string().regex(/^[a-z0-9][a-z0-9-]*$/).max(40),
37
- label: z.string().min(1).max(60),
38
- icon: z.string().max(40).optional(),
39
- sections: z.array(dashboardSectionSchema).min(1),
40
- });
41
- export const dashboardLayoutSchema = z.object({
42
- version: z.literal(1),
43
- pages: z.array(dashboardPageSchema).min(1).max(8),
44
- });
45
- // ---------------------------------------------------------------------------
46
- // Default dashboard layout generator
47
- // ---------------------------------------------------------------------------
48
- const defaultIdFactory = () => crypto.randomUUID();
49
- /** Structural port of the legacy hardcoded dashboard config into a single
50
- * 'Overview' page. Widgets fetch their own data: configs carry only the
51
- * variant and (where relevant) the default seed binding. */
52
- export function generateDefaultDashboardLayout(seeds, opts) {
53
- const newId = opts?.newId ?? defaultIdFactory;
54
- const widget = (type, config) => ({ id: newId(), type, config });
55
- const singleWidgetColumn = (w) => ({
56
- id: newId(),
57
- widgets: [w],
58
- });
59
- const sections = [];
60
- // Setup checklist, full width.
61
- sections.push({
62
- id: newId(),
63
- hideLabel: true,
64
- columns: [singleWidgetColumn(widget('core/setup-checklist', { variant: 'full' }))],
65
- });
66
- // Status row: equal columns; quick-draft needs at least one seed to target.
67
- const statusWidgets = [
68
- widget('core/site-status', { variant: 'badge' }),
69
- widget('core/storage', { variant: 'gauge' }),
70
- widget('core/publication-stats', { variant: 'trio' }),
71
- ];
72
- if (seeds.length > 0) {
73
- statusWidgets.push(widget('core/quick-draft', { variant: 'minimal' }));
74
- }
75
- sections.push({
76
- id: newId(),
77
- hideLabel: true,
78
- columns: statusWidgets.map(singleWidgetColumn),
79
- });
80
- if (seeds.length > 0) {
81
- const seedSlug = seeds.find((s) => s.slug === 'articoli')?.slug ?? seeds[0].slug;
82
- // Content row: recent content | pending drafts.
83
- sections.push({
84
- id: newId(),
85
- hideLabel: true,
86
- columns: [
87
- singleWidgetColumn(widget('core/recent-content', { seedSlug, variant: 'list' })),
88
- singleWidgetColumn(widget('core/pending-drafts', { seedSlug, variant: 'list' })),
89
- ],
90
- columnSpans: [6, 6],
91
- });
92
- // Media & activity row: media gallery | activity feed.
93
- sections.push({
94
- id: newId(),
95
- hideLabel: true,
96
- columns: [
97
- singleWidgetColumn(widget('core/media-gallery', { seedSlug, variant: 'grid' })),
98
- singleWidgetColumn(widget('core/activity-feed', { seedSlug, variant: 'feed' })),
99
- ],
100
- columnSpans: [6, 6],
101
- });
102
- }
103
- return {
104
- version: 1,
105
- pages: [
106
- {
107
- id: newId(),
108
- slug: 'overview',
109
- label: 'Overview',
110
- icon: 'LayoutDashboard',
111
- sections,
112
- },
113
- ],
114
- };
115
- }
116
- /** Semantic validation on top of the Zod shape check (the caller's job).
117
- * Widgets bound to a seed that no longer exists are silently stripped
118
- * (auto-cleanup, recorded as a warning). Unknown widget types only warn —
119
- * custom widgets are invisible to the Worker and must never be stripped.
120
- * `cleaned` is always returned, errors or not. */
121
- export function validateDashboardLayout(layout, ctx) {
122
- const errors = [];
123
- const warnings = [];
124
- // Auto-cleanup: drop widgets whose config.seedSlug references a missing seed.
125
- const cleanedPages = layout.pages.map((page) => ({
126
- ...page,
127
- sections: page.sections.map((section) => ({
128
- ...section,
129
- columns: section.columns.map((col) => ({
130
- ...col,
131
- widgets: (col.widgets ?? []).filter((w) => {
132
- const seedSlug = (w.config ?? {})['seedSlug'];
133
- if (typeof seedSlug === 'string' && !ctx.seedSlugs.has(seedSlug)) {
134
- warnings.push(`Widget '${w.type}' (id=${w.id}) removed: seed '${seedSlug}' is not registered.`);
135
- return false;
136
- }
137
- return true;
138
- }),
139
- })),
140
- })),
141
- }));
142
- // Semantic checks on the cleaned layout
143
- const seenWidgetIds = new Set();
144
- const seenPageSlugs = new Set();
145
- for (const page of cleanedPages) {
146
- if (seenPageSlugs.has(page.slug)) {
147
- errors.push(`Page slug '${page.slug}' appears more than once in the layout.`);
148
- }
149
- else {
150
- seenPageSlugs.add(page.slug);
151
- }
152
- for (const section of page.sections) {
153
- if (section.columnSpans !== undefined) {
154
- if (section.columnSpans.length !== section.columns.length) {
155
- errors.push(`Section ${section.id}: columnSpans has ${section.columnSpans.length} entries for ${section.columns.length} columns.`);
156
- }
157
- else {
158
- const sum = section.columnSpans.reduce((acc, span) => acc + span, 0);
159
- if (sum !== 12) {
160
- errors.push(`Section ${section.id}: columnSpans must sum to 12, got ${sum}.`);
161
- }
162
- }
163
- }
164
- for (const col of section.columns) {
165
- for (const w of col.widgets) {
166
- if (seenWidgetIds.has(w.id)) {
167
- errors.push(`Widget id '${w.id}' appears more than once in the layout.`);
168
- }
169
- else {
170
- seenWidgetIds.add(w.id);
171
- }
172
- if (JSON.stringify(w.config ?? {}).length > MAX_WIDGET_CONFIG_BYTES) {
173
- errors.push(`Widget '${w.type}' (id=${w.id}): config exceeds ${MAX_WIDGET_CONFIG_BYTES} bytes when serialized.`);
174
- }
175
- if (ctx.knownWidgetTypes !== undefined && !ctx.knownWidgetTypes.has(w.type)) {
176
- warnings.push(`Widget '${w.type}' (id=${w.id}) is not a known widget type.`);
177
- }
178
- }
179
- }
180
- }
181
- }
182
- const cleaned = { ...layout, pages: cleanedPages };
183
- if (errors.length > 0)
184
- return { ok: false, errors, cleaned, warnings };
185
- return { ok: true, cleaned, warnings };
186
- }
@@ -1,18 +0,0 @@
1
- import type { DashboardLayout } from './dashboard-layout.js';
2
- export interface DashboardLayoutRecord {
3
- scope: string;
4
- layout: DashboardLayout;
5
- updatedAt: number;
6
- updatedBy: string;
7
- }
8
- export interface IDashboardLayoutRepository {
9
- /** Stored layout for a scope, or null if none was ever saved. */
10
- get(scope: string): Promise<DashboardLayoutRecord | null>;
11
- /** Scopes that currently have a stored row — used by the Sprint 06 builder UI. */
12
- listScopes(): Promise<string[]>;
13
- /** Upsert. `updatedBy` is the writer's user id. */
14
- upsert(scope: string, layout: DashboardLayout, updatedBy: string): Promise<void>;
15
- /** Remove the stored row — the "Reset" action. */
16
- remove(scope: string): Promise<void>;
17
- }
18
- //# sourceMappingURL=dashboard-layout.repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-layout.repository.d.ts","sourceRoot":"","sources":["../src/dashboard-layout.repository.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,eAAe,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,iEAAiE;IACjE,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;IACzD,kFAAkF;IAClF,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC/B,mDAAmD;IACnD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChF,kDAAkD;IAClD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC"}
@@ -1,3 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- export {};
@@ -1,3 +0,0 @@
1
- export declare const ROLES_ALLOWED_TO_EDIT_DASHBOARD: ReadonlyArray<string>;
2
- export declare function canEditDashboard(role: string | undefined | null): boolean;
3
- //# sourceMappingURL=dashboard-permissions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-permissions.d.ts","sourceRoot":"","sources":["../src/dashboard-permissions.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,+BAA+B,EAAE,aAAa,CAAC,MAAM,CAAa,CAAA;AAE/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAGzE"}
@@ -1,11 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- // NOTE: change this list to extend write-access to other roles
4
- // (e.g. add 'editor', or introduce a fine-grained 'dashboard:edit' permission).
5
- // Single source of truth — used by both API guards and dashboard buttons.
6
- export const ROLES_ALLOWED_TO_EDIT_DASHBOARD = ['admin'];
7
- export function canEditDashboard(role) {
8
- if (!role)
9
- return false;
10
- return ROLES_ALLOWED_TO_EDIT_DASHBOARD.includes(role);
11
- }
@@ -1,12 +0,0 @@
1
- /** Roles that may have their own dashboard layout. Single source of truth —
2
- * extend this list if a new role is introduced. */
3
- export declare const KNOWN_DASHBOARD_ROLES: ReadonlyArray<string>;
4
- export declare const DEFAULT_DASHBOARD_SCOPE = "default";
5
- /** Builds the per-role scope string, e.g. `roleScope('editor') === 'role:editor'`. */
6
- export declare function roleScope(role: string): string;
7
- /** Whether `scope` is one of the closed set: `'default' | 'role:<known role>'`. */
8
- export declare function isValidDashboardScope(scope: string): boolean;
9
- /** Read-resolution order for a caller's role: `['role:<role>', 'default']`,
10
- * or just `['default']` for unknown/missing roles. */
11
- export declare function resolveDashboardScopeChain(role: string | undefined | null): string[];
12
- //# sourceMappingURL=dashboard-scopes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-scopes.d.ts","sourceRoot":"","sources":["../src/dashboard-scopes.ts"],"names":[],"mappings":"AAOA;oDACoD;AACpD,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAAuB,CAAA;AAE/E,eAAO,MAAM,uBAAuB,YAAY,CAAA;AAEhD,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK5D;AAED;uDACuD;AACvD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAKpF"}
@@ -1,30 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- // ---------------------------------------------------------------------------
4
- // Dashboard layout scopes (Sprint 06: role-based dashboards)
5
- // ---------------------------------------------------------------------------
6
- /** Roles that may have their own dashboard layout. Single source of truth —
7
- * extend this list if a new role is introduced. */
8
- export const KNOWN_DASHBOARD_ROLES = ['admin', 'editor'];
9
- export const DEFAULT_DASHBOARD_SCOPE = 'default';
10
- /** Builds the per-role scope string, e.g. `roleScope('editor') === 'role:editor'`. */
11
- export function roleScope(role) {
12
- return `role:${role}`;
13
- }
14
- /** Whether `scope` is one of the closed set: `'default' | 'role:<known role>'`. */
15
- export function isValidDashboardScope(scope) {
16
- if (scope === DEFAULT_DASHBOARD_SCOPE)
17
- return true;
18
- const match = /^role:(.+)$/.exec(scope);
19
- if (!match)
20
- return false;
21
- return KNOWN_DASHBOARD_ROLES.includes(match[1]);
22
- }
23
- /** Read-resolution order for a caller's role: `['role:<role>', 'default']`,
24
- * or just `['default']` for unknown/missing roles. */
25
- export function resolveDashboardScopeChain(role) {
26
- if (role && KNOWN_DASHBOARD_ROLES.includes(role)) {
27
- return [roleScope(role), DEFAULT_DASHBOARD_SCOPE];
28
- }
29
- return [DEFAULT_DASHBOARD_SCOPE];
30
- }
@@ -1,3 +0,0 @@
1
- import type { Seed } from './types.js';
2
- export declare function defineSeed(seed: Seed): Seed;
3
- //# sourceMappingURL=define-seed.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"define-seed.d.ts","sourceRoot":"","sources":["../src/define-seed.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAE3C"}
@@ -1,5 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- export function defineSeed(seed) {
4
- return seed;
5
- }
@@ -1,5 +0,0 @@
1
- export interface IDemoDataRepository {
2
- /** Executes the compiled demo dataset SQL against the database. */
3
- loadDemoData(): Promise<void>;
4
- }
5
- //# sourceMappingURL=demo-data.repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"demo-data.repository.d.ts","sourceRoot":"","sources":["../src/demo-data.repository.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9B"}
@@ -1,3 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Copyright (c) 2024–2026 Flavio De Musso
3
- export {};
@@ -1,32 +0,0 @@
1
- /**
2
- * The resolved email message that the provider receives and sends.
3
- * Constructed by the service by combining call parameters with template builder output.
4
- */
5
- export interface OutboundEmail {
6
- /** Sender address in RFC 5321 format (e.g., "Beech CMS <noreply@beechcms.dev>"). */
7
- from: string;
8
- /** List of recipient addresses. Must contain at least one element. */
9
- to: string[];
10
- subject: string;
11
- /** Complete HTML body. Must be a valid HTML document (see templates/shell.ts). */
12
- html: string;
13
- }
14
- /**
15
- * Formal contract for email sending providers.
16
- *
17
- * Every implementation (Resend, SMTP, …) must comply with this interface.
18
- * It is the only point of coupling between the email module and any external service.
19
- *
20
- * To add a new provider: create a class in apps/api/src/shared/email/providers/
21
- * that implements this interface, then wire it in email.service.ts.
22
- */
23
- export interface EmailProvider {
24
- /**
25
- * Sends a single transactional email.
26
- *
27
- * @throws {Error} If the provider rejects the request. The caller is responsible
28
- * for catching and handling this error appropriately.
29
- */
30
- send(email: OutboundEmail): Promise<void>;
31
- }
32
- //# sourceMappingURL=email.provider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email.provider.d.ts","sourceRoot":"","sources":["../src/email.provider.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,EAAE,EAAE,MAAM,EAAE,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C"}
@@ -1,4 +0,0 @@
1
- // SPDX-License-Identifier: BUSL-1.1
2
- // Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
3
- // See LICENSE in the repository root for license terms.
4
- export {};
@@ -1,40 +0,0 @@
1
- import type { Seed, BranchType } from '../types.js';
2
- /**
3
- * Ordered DROP TABLE statements for a full hard-delete of a seed's tables.
4
- * Order: junction drafts → junctions → FTS triggers → FTS table → drafts → main table.
5
- * All statements use IF EXISTS (idempotent).
6
- */
7
- export declare function generateDropTable(seed: Seed): string[];
8
- /**
9
- * DROP COLUMN statements for a single branch (by alias).
10
- * For multi-relation branches: drops the junction tables (no column on parent).
11
- * For regular branches: drops from main table + drafts table (if allowDrafts).
12
- * Does NOT include FTS handling — callers must prepend ftsTriggerDrops() and
13
- * append planFtsRebuild() when the branch is searchable.
14
- */
15
- export declare function generateDropColumn(seed: Seed, alias: string): string[];
16
- /**
17
- * RENAME COLUMN statements for a branch alias change.
18
- * Updates main table + drafts (if allowDrafts).
19
- * Does NOT handle FTS — callers must rebuild FTS separately (SQLite auto-updates
20
- * trigger bodies on RENAME but the FTS virtual-table columns keep the old name).
21
- */
22
- export declare function generateRenameColumn(seed: Seed, fromAlias: string, toAlias: string): string[];
23
- /**
24
- * Full FTS rebuild: drop triggers + FTS table, then recreate them, then backfill.
25
- * Returns an empty array if the seed has no searchable branches.
26
- * The drop steps use IF EXISTS so this is safe to call even if FTS was already dropped.
27
- */
28
- export declare function planFtsRebuild(seed: Seed): string[];
29
- export interface RetypeColumnPlan {
30
- statements: string[];
31
- ftsRebuildNeeded: boolean;
32
- }
33
- /**
34
- * Generates statements to change a branch's SQL storage type using the
35
- * add-new-column / copy / drop-old / rename approach.
36
- * Includes FTS rebuild statements when the branch is (or becomes) searchable.
37
- * `updatedSeed` must already reflect the new type on the renamed branch.
38
- */
39
- export declare function planRetypeColumn(seed: Seed, alias: string, newType: BranchType, updatedSeed: Seed): RetypeColumnPlan;
40
- //# sourceMappingURL=seed-ddl-destructive.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-ddl-destructive.d.ts","sourceRoot":"","sources":["../../../src/engine/ddl/seed-ddl-destructive.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAU,UAAU,EAAE,MAAM,aAAa,CAAA;AAkC3D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAgBtD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBtE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ7F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAiBnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,UAAU,EACnB,WAAW,EAAE,IAAI,GAChB,gBAAgB,CAyClB"}