@beechcms/core 0.4.0-preview.1 → 0.4.0-preview.11

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.
@@ -0,0 +1,95 @@
1
+ import { Seed, SelectOptions } from './types.js';
2
+ /**
3
+ * Base Repository Error
4
+ */
5
+ export declare class RepositoryError extends Error {
6
+ cause?: unknown | undefined;
7
+ constructor(message: string, cause?: unknown | undefined);
8
+ }
9
+ /**
10
+ * Thrown when an entry is not found by ID or Slug
11
+ */
12
+ export declare class EntryNotFoundError extends RepositoryError {
13
+ constructor(message: string);
14
+ }
15
+ /**
16
+ * Thrown when a slug already exists for a content type
17
+ */
18
+ export declare class SlugConflictError extends RepositoryError {
19
+ constructor(message: string);
20
+ }
21
+ /**
22
+ * Interface defining the standard operations for content persistence.
23
+ * This is platform-agnostic and should be implemented for specific databases (e.g., D1).
24
+ */
25
+ export interface ContentRepository {
26
+ /**
27
+ * Retrieves a paginated and filtered list of entries.
28
+ */
29
+ findMany(seed: Seed, options: SelectOptions): Promise<{
30
+ items: Record<string, any>[];
31
+ total: number;
32
+ }>;
33
+ /**
34
+ * Finds a single entry by its unique ID.
35
+ * Throws EntryNotFoundError if not found.
36
+ */
37
+ findById(seed: Seed, id: string): Promise<Record<string, any>>;
38
+ /**
39
+ * Finds a single entry by its unique slug.
40
+ * Throws EntryNotFoundError if not found.
41
+ */
42
+ findBySlug(seed: Seed, slug: string): Promise<Record<string, any>>;
43
+ /**
44
+ * Computes facets (status counts and distinct tags) for a content type.
45
+ */
46
+ getFacets(seed: Seed): Promise<{
47
+ statuses: Record<string, number>;
48
+ tagsByColumn: Record<string, string[]>;
49
+ }>;
50
+ /**
51
+ * Creates a new content entry in the live table.
52
+ * Throws SlugConflictError if the slug is already taken.
53
+ */
54
+ create(seed: Seed, id: string, slug: string, status: string, data: Record<string, any>): Promise<void>;
55
+ /**
56
+ * Partially updates an existing entry in the live table.
57
+ * Throws EntryNotFoundError if the ID does not exist.
58
+ */
59
+ update(seed: Seed, id: string, data: Record<string, any>, status?: string): Promise<void>;
60
+ /**
61
+ * Deletes an entry from the live table.
62
+ * Returns the deleted row data (useful for media cleanup).
63
+ * Throws EntryNotFoundError if the ID does not exist.
64
+ */
65
+ delete(seed: Seed, id: string): Promise<{
66
+ row: Record<string, any>;
67
+ }>;
68
+ /**
69
+ * Saves or updates a pending draft in the mirror table.
70
+ */
71
+ saveDraft(seed: Seed, entryId: string, data: Record<string, any>): Promise<void>;
72
+ /**
73
+ * Retrieves the pending draft for a given entry.
74
+ * Returns null if no draft exists.
75
+ */
76
+ getDraft(seed: Seed, entryId: string): Promise<Record<string, any> | null>;
77
+ /**
78
+ * Atomic promotion of a draft to the live table.
79
+ * Must use a transaction (db.batch) to update live and delete draft.
80
+ */
81
+ publishDraft(seed: Seed, entryId: string): Promise<void>;
82
+ /**
83
+ * Discards the pending draft.
84
+ */
85
+ deleteDraft(seed: Seed, entryId: string): Promise<void>;
86
+ /**
87
+ * Checks if a slug is already taken by another entry.
88
+ */
89
+ existsSlug(seed: Seed, slug: string, excludeId?: string): Promise<boolean>;
90
+ /**
91
+ * Checks if an entry has a pending draft.
92
+ */
93
+ hasDraft(seed: Seed, entryId: string): Promise<boolean>;
94
+ }
95
+ //# sourceMappingURL=content.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.repository.d.ts","sourceRoot":"","sources":["../src/content.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Base Repository Error
3
+ */
4
+ export class RepositoryError extends Error {
5
+ cause;
6
+ constructor(message, cause) {
7
+ super(message);
8
+ this.cause = cause;
9
+ this.name = 'RepositoryError';
10
+ }
11
+ }
12
+ /**
13
+ * Thrown when an entry is not found by ID or Slug
14
+ */
15
+ export class EntryNotFoundError extends RepositoryError {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'EntryNotFoundError';
19
+ }
20
+ }
21
+ /**
22
+ * Thrown when a slug already exists for a content type
23
+ */
24
+ export class SlugConflictError extends RepositoryError {
25
+ constructor(message) {
26
+ super(message);
27
+ this.name = 'SlugConflictError';
28
+ }
29
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,IAAI,EACJ,MAAM,EAKN,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAA;AA+EnB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAsBtD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAuB5D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAkBpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAc1D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAgCxD;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,kBAAkB,CAqE5F;AA0CD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,EAAE,CAc7D;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAkCrF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA4BzE"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,IAAI,EACJ,MAAM,EAKN,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAgFnB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAsBtD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAuB5D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAkBpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAc1D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAgCxD;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,kBAAkB,CAqE5F;AA+GD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,EAAE,CAc7D;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAmCrF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA6BzE"}
package/dist/engine.js CHANGED
@@ -6,6 +6,7 @@ const BRANCH_TYPE_SQL = {
6
6
  json: { sqlType: 'TEXT' }, // JSON serializzato
7
7
  richtext: { sqlType: 'TEXT' },
8
8
  file: { sqlType: 'TEXT' }, // URL singolo o JSON array di URL
9
+ tags: { sqlType: 'TEXT' }, // JSON array di stringhe
9
10
  };
10
11
  const SYSTEM_COLUMNS = new Set(['id', 'slug', 'status', 'created_at', 'updated_at']);
11
12
  // ---- Private helpers ----
@@ -277,6 +278,32 @@ export function buildSelectQuery(seed, options = {}) {
277
278
  }
278
279
  return { sql, bindings };
279
280
  }
281
+ function normalizeFilterValue(type, value) {
282
+ if (value === null || value === undefined)
283
+ return null;
284
+ if (type === 'date') {
285
+ if (typeof value === 'number')
286
+ return value;
287
+ if (typeof value === 'string' && value.trim() !== '') {
288
+ const d = new Date(value);
289
+ return isNaN(d.getTime()) ? null : Math.floor(d.getTime() / 1000);
290
+ }
291
+ return null;
292
+ }
293
+ if (type === 'boolean') {
294
+ return value ? 1 : 0;
295
+ }
296
+ if (type === 'number') {
297
+ if (typeof value === 'number')
298
+ return value;
299
+ if (typeof value === 'string' && value.trim() !== '') {
300
+ const n = Number(value);
301
+ return isNaN(n) ? null : n;
302
+ }
303
+ return null;
304
+ }
305
+ return value;
306
+ }
280
307
  function buildFilterCondition(col, type, cond, bindings) {
281
308
  const { op, value } = cond;
282
309
  if (op === 'is_empty') {
@@ -285,23 +312,58 @@ function buildFilterCondition(col, type, cond, bindings) {
285
312
  if (op === 'is_not_empty') {
286
313
  return type === 'text' ? `(${col} IS NOT NULL AND ${col} != '')` : `${col} IS NOT NULL`;
287
314
  }
288
- if (value === null || value === undefined)
289
- return null;
290
- if (op === 'eq') {
291
- bindings.push(type === 'boolean' ? (value ? 1 : 0) : value);
292
- return `${col} = ?`;
315
+ if (op === 'in' || op === 'not_in') {
316
+ if (!Array.isArray(value) || value.length === 0)
317
+ return null;
318
+ const normalizedValues = value
319
+ .map((v) => normalizeFilterValue(type, v))
320
+ .filter((v) => v !== null);
321
+ if (normalizedValues.length === 0)
322
+ return null;
323
+ const placeholders = normalizedValues.map(() => '?').join(', ');
324
+ bindings.push(...normalizedValues);
325
+ return `${col} ${op === 'in' ? 'IN' : 'NOT IN'} (${placeholders})`;
293
326
  }
294
- if (op === 'contains') {
295
- if (type === 'tags') {
296
- bindings.push(String(value));
297
- return `EXISTS (SELECT 1 FROM json_each(${col}) WHERE value = ?)`;
327
+ if (op === 'has_tag' || op === 'has_any_tag' || op === 'has_all_tags') {
328
+ if (type !== 'tags' && type !== 'json')
329
+ return null;
330
+ const tags = (op === 'has_tag' ? [value] : Array.isArray(value) ? value : [value])
331
+ .map(t => String(t));
332
+ if (tags.length === 0)
333
+ return null;
334
+ if (op === 'has_tag' || op === 'has_any_tag') {
335
+ const placeholders = tags.map(() => '?').join(', ');
336
+ bindings.push(...tags);
337
+ return `EXISTS (SELECT 1 FROM json_each(${col}) WHERE value IN (${placeholders}))`;
298
338
  }
299
- bindings.push(`%${String(value)}%`);
300
- return `${col} LIKE ?`;
339
+ // has_all_tags: each tag must exist
340
+ const clauses = tags.map(() => `EXISTS (SELECT 1 FROM json_each(${col}) WHERE value = ?)`);
341
+ bindings.push(...tags);
342
+ return `(${clauses.join(' AND ')})`;
343
+ }
344
+ const normalized = normalizeFilterValue(type, value);
345
+ if (normalized === null)
346
+ return null;
347
+ if (op === 'eq' || op === 'neq') {
348
+ const sqlOp = op === 'eq' ? '=' : '!=';
349
+ bindings.push(normalized);
350
+ return `${col} ${sqlOp} ?`;
351
+ }
352
+ if (op === 'contains' || op === 'not_contains' || op === 'starts_with' || op === 'ends_with') {
353
+ const sqlOp = op === 'not_contains' ? 'NOT LIKE' : 'LIKE';
354
+ let pattern = String(value);
355
+ if (op === 'contains' || op === 'not_contains')
356
+ pattern = `%${pattern}%`;
357
+ else if (op === 'starts_with')
358
+ pattern = `${pattern}%`;
359
+ else if (op === 'ends_with')
360
+ pattern = `%${pattern}`;
361
+ bindings.push(pattern);
362
+ return `${col} ${sqlOp} ?`;
301
363
  }
302
364
  const mathOps = { gt: '>', gte: '>=', lt: '<', lte: '<=' };
303
365
  if (mathOps[op]) {
304
- bindings.push(value);
366
+ bindings.push(normalized);
305
367
  return `${col} ${mathOps[op]} ?`;
306
368
  }
307
369
  return null;
@@ -337,6 +399,7 @@ export function serializeForDb(branch, value) {
337
399
  case 'boolean':
338
400
  return value ? 1 : 0;
339
401
  case 'json':
402
+ case 'tags':
340
403
  case 'richtext':
341
404
  return typeof value === 'string' ? value : JSON.stringify(value);
342
405
  case 'date': {
@@ -374,6 +437,7 @@ export function deserializeFromDb(branch, value) {
374
437
  case 'boolean':
375
438
  return value === 1 || value === true;
376
439
  case 'json':
440
+ case 'tags':
377
441
  case 'richtext': {
378
442
  if (typeof value === 'string') {
379
443
  try {
@@ -0,0 +1,13 @@
1
+ export interface IdempotencyRecord {
2
+ key: string;
3
+ fingerprint: string;
4
+ responseStatus: number;
5
+ responseBody: string;
6
+ expiresAt: number;
7
+ }
8
+ export interface IdempotencyRepository {
9
+ lookup(key: string): Promise<IdempotencyRecord | null>;
10
+ store(record: IdempotencyRecord): Promise<void>;
11
+ cleanup(now: number): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=idempotency.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.repository.d.ts","sourceRoot":"","sources":["../src/idempotency.repository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IACtD,KAAK,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpC"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -15,5 +15,7 @@ export * from './validation.js';
15
15
  export * from './richtext.js';
16
16
  export * from './richtext-render.js';
17
17
  export * from './slug-utils.js';
18
+ export * from './content.repository.js';
19
+ export * from './idempotency.repository.js';
18
20
  export * from './policies.js';
19
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -15,4 +15,6 @@ export * from './validation.js';
15
15
  export * from './richtext.js';
16
16
  export * from './richtext-render.js';
17
17
  export * from './slug-utils.js';
18
+ export * from './content.repository.js';
19
+ export * from './idempotency.repository.js';
18
20
  export * from './policies.js';
package/dist/seeds.d.ts CHANGED
@@ -4,33 +4,17 @@
4
4
  * `branch.alias` è il nome della colonna SQL.
5
5
  */
6
6
  import type { Seed } from './types.js';
7
- /** Articolo: contenuto editoriale con richtext, immagine e SEO */
8
- export declare const ARTICOLO_SEED: Seed;
9
- /** Prodotto: scheda prodotto e-commerce con richtext, galleria e SEO */
10
- export declare const PRODOTTO_SEED: Seed;
11
- /** Membro del team: profilo con foto e link social */
12
- export declare const TEAM_SEED: Seed;
13
- /** Testimonianza: recensione cliente con valutazione e foto */
14
- export declare const TESTIMONIANZA_SEED: Seed;
15
- /** Pagina: pagina statica con richtext, immagine hero e SEO */
16
- export declare const PAGINA_SEED: Seed;
17
7
  /**
18
- * Cliente: dimostra tutte le assi di Branch.policies.
19
- *
20
- * email → visibility:masked, search:false, public:false
21
- * passwordHash → privacy:hash, visibility:hidden, search/filter/sort/public: false
22
- * phone → visibility:masked, filter:false, public:false
23
- * internalNote → visibility:hidden, search:false, public:false
24
- * registeredAt → public:false (data interna, non esposta)
8
+ * Registro globale dei Seed.
9
+ * In produzione, questo viene popolato dalle definizioni dell'utente.
25
10
  */
26
- export declare const CLIENTE_SEED: Seed;
11
+ export declare const SEED_REGISTRY: Record<string, Seed>;
27
12
  /**
28
- * TODO: Rimuovere al termine dei test del testsite
29
- * Messaggio di contatto: per form contatti esterni
13
+ * Registra un set di Seed nel registro globale.
14
+ */
15
+ export declare function registerSeeds(seeds: Seed[]): void;
16
+ /**
17
+ * Ritorna il Seed per lo slug dato, o null se non esiste.
30
18
  */
31
- export declare const MESSAGGI_SEED: Seed;
32
- /** Registro: slug -> Seed */
33
- export declare const SEED_REGISTRY: Record<string, Seed>;
34
- /** Ritorna il Seed per lo slug dato, o null se non esiste. */
35
19
  export declare function getSeed(slug: string): Seed | null;
36
20
  //# sourceMappingURL=seeds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seeds.d.ts","sourceRoot":"","sources":["../src/seeds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,kEAAkE;AAClE,eAAO,MAAM,aAAa,EAAE,IAgB3B,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,aAAa,EAAE,IAiB3B,CAAA;AAED,sDAAsD;AACtD,eAAO,MAAM,SAAS,EAAE,IAgBvB,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,EAAE,IAiBhC,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,IAczB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,IA8C1B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,IAc3B,CAAA;AAED,6BAA6B;AAC7B,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAQ9C,CAAA;AAED,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjD"}
1
+ {"version":3,"file":"seeds.d.ts","sourceRoot":"","sources":["../src/seeds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAM,CAAA;AAErD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,QAI1C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjD"}
package/dist/seeds.js CHANGED
@@ -1,179 +1,19 @@
1
- /** Articolo: contenuto editoriale con richtext, immagine e SEO */
2
- export const ARTICOLO_SEED = {
3
- slug: 'articoli',
4
- label: 'Articolo',
5
- labelPlural: 'Articoli',
6
- displayNameAlias: 'title',
7
- allowPublicRead: true,
8
- allowDrafts: true,
9
- branches: [
10
- { alias: 'title', label: 'Titolo', type: 'text' },
11
- { alias: 'publishedAt', label: 'Data pubblicazione', type: 'date' },
12
- { alias: 'coverImage', label: 'Immagine copertina', type: 'file' },
13
- { alias: 'tags', label: 'Tag', type: 'json', options: ['cms', 'tutorial', 'release', 'annuncio', 'guida', 'news', 'aggiornamento'] },
14
- { alias: 'body', label: 'Corpo articolo', type: 'richtext' },
15
- { alias: 'metaTitle', label: 'Meta titolo (SEO)', type: 'text' },
16
- { alias: 'metaDescription', label: 'Meta descrizione (SEO)', type: 'text' },
17
- ],
18
- };
19
- /** Prodotto: scheda prodotto e-commerce con richtext, galleria e SEO */
20
- export const PRODOTTO_SEED = {
21
- slug: 'prodotti',
22
- label: 'Prodotto',
23
- labelPlural: 'Prodotti',
24
- displayNameAlias: 'name',
25
- allowPublicRead: true,
26
- branches: [
27
- { alias: 'name', label: 'Nome', type: 'text' },
28
- { alias: 'price', label: 'Prezzo (€)', type: 'number' },
29
- { alias: 'stock', label: 'Quantità disponibile', type: 'number' },
30
- { alias: 'active', label: 'In vendita', type: 'boolean' },
31
- { alias: 'coverImage', label: 'Immagine principale', type: 'file' },
32
- { alias: 'images', label: 'Galleria immagini', type: 'file', multiple: true, format: 'asset-list' },
33
- { alias: 'description', label: 'Descrizione', type: 'richtext' },
34
- { alias: 'metaTitle', label: 'Meta titolo (SEO)', type: 'text' },
35
- { alias: 'metaDescription', label: 'Meta descrizione (SEO)', type: 'text' },
36
- ],
37
- };
38
- /** Membro del team: profilo con foto e link social */
39
- export const TEAM_SEED = {
40
- slug: 'team',
41
- label: 'Membro',
42
- labelPlural: 'Team',
43
- displayNameAlias: 'name',
44
- allowPublicRead: true,
45
- branches: [
46
- { alias: 'name', label: 'Nome', type: 'text' },
47
- { alias: 'role', label: 'Ruolo', type: 'text' },
48
- { alias: 'bio', label: 'Bio breve', type: 'text' },
49
- { alias: 'photo', label: 'Foto', type: 'file' },
50
- { alias: 'linkedIn', label: 'URL LinkedIn', type: 'text' },
51
- { alias: 'active', label: 'Visibile', type: 'boolean' },
52
- { alias: 'metaTitle', label: 'Meta titolo (SEO)', type: 'text' },
53
- { alias: 'metaDescription', label: 'Meta descrizione (SEO)', type: 'text' },
54
- ],
55
- };
56
- /** Testimonianza: recensione cliente con valutazione e foto */
57
- export const TESTIMONIANZA_SEED = {
58
- slug: 'testimonianze',
59
- label: 'Testimonianza',
60
- labelPlural: 'Testimonianze',
61
- displayNameAlias: 'author',
62
- allowPublicRead: true,
63
- branches: [
64
- { alias: 'author', label: 'Autore', type: 'text' },
65
- { alias: 'company', label: 'Azienda', type: 'text' },
66
- { alias: 'quote', label: 'Citazione', type: 'text' },
67
- { alias: 'rating', label: 'Valutazione (1-5)', type: 'number' },
68
- { alias: 'date', label: 'Data', type: 'date' },
69
- { alias: 'photo', label: 'Foto autore', type: 'file' },
70
- { alias: 'active', label: 'Pubblica', type: 'boolean' },
71
- { alias: 'metaTitle', label: 'Meta titolo (SEO)', type: 'text' },
72
- { alias: 'metaDescription', label: 'Meta descrizione (SEO)', type: 'text' },
73
- ],
74
- };
75
- /** Pagina: pagina statica con richtext, immagine hero e SEO */
76
- export const PAGINA_SEED = {
77
- slug: 'pagine',
78
- label: 'Pagina',
79
- labelPlural: 'Pagine',
80
- displayNameAlias: 'title',
81
- allowPublicRead: true,
82
- allowDrafts: true,
83
- branches: [
84
- { alias: 'title', label: 'Titolo', type: 'text' },
85
- { alias: 'coverImage', label: 'Immagine hero', type: 'file' },
86
- { alias: 'body', label: 'Contenuto', type: 'richtext' },
87
- { alias: 'metaTitle', label: 'Meta titolo (SEO)', type: 'text' },
88
- { alias: 'metaDescription', label: 'Meta descrizione (SEO)', type: 'text' },
89
- ],
90
- };
91
1
  /**
92
- * Cliente: dimostra tutte le assi di Branch.policies.
93
- *
94
- * email → visibility:masked, search:false, public:false
95
- * passwordHash → privacy:hash, visibility:hidden, search/filter/sort/public: false
96
- * phone → visibility:masked, filter:false, public:false
97
- * internalNote → visibility:hidden, search:false, public:false
98
- * registeredAt → public:false (data interna, non esposta)
2
+ * Registro globale dei Seed.
3
+ * In produzione, questo viene popolato dalle definizioni dell'utente.
99
4
  */
100
- export const CLIENTE_SEED = {
101
- slug: 'clienti',
102
- label: 'Cliente',
103
- labelPlural: 'Clienti',
104
- displayNameAlias: 'name',
105
- allowPublicRead: true,
106
- branches: [
107
- { alias: 'name', label: 'Nome', type: 'text' },
108
- {
109
- alias: 'email',
110
- label: 'Email',
111
- type: 'text',
112
- policies: { visibility: 'masked', search: false, public: false },
113
- },
114
- {
115
- alias: 'passwordHash',
116
- label: 'Password (hash)',
117
- type: 'text',
118
- policies: { privacy: 'hash', visibility: 'hidden', search: false, filter: false, sort: false, public: false },
119
- },
120
- {
121
- alias: 'tier',
122
- label: 'Piano',
123
- type: 'text',
124
- options: ['free', 'starter', 'pro', 'enterprise'],
125
- },
126
- {
127
- alias: 'phone',
128
- label: 'Telefono',
129
- type: 'text',
130
- policies: { visibility: 'masked', filter: false, public: false },
131
- },
132
- {
133
- alias: 'internalNote',
134
- label: 'Note interne',
135
- type: 'text',
136
- policies: { visibility: 'hidden', search: false, public: false },
137
- },
138
- {
139
- alias: 'registeredAt',
140
- label: 'Data iscrizione',
141
- type: 'date',
142
- policies: { public: false },
143
- },
144
- { alias: 'active', label: 'Attivo', type: 'boolean' },
145
- ],
146
- };
5
+ export const SEED_REGISTRY = {};
147
6
  /**
148
- * TODO: Rimuovere al termine dei test del testsite
149
- * Messaggio di contatto: per form contatti esterni
7
+ * Registra un set di Seed nel registro globale.
8
+ */
9
+ export function registerSeeds(seeds) {
10
+ seeds.forEach(seed => {
11
+ SEED_REGISTRY[seed.slug] = seed;
12
+ });
13
+ }
14
+ /**
15
+ * Ritorna il Seed per lo slug dato, o null se non esiste.
150
16
  */
151
- export const MESSAGGI_SEED = {
152
- slug: 'messaggi',
153
- label: 'Messaggio',
154
- labelPlural: 'Messaggi',
155
- displayNameAlias: 'name',
156
- allowPublicPost: true,
157
- allowPublicEdit: true,
158
- branches: [
159
- { alias: 'name', label: 'Nome mittente', type: 'text', requiredOnCreate: true },
160
- { alias: 'email', label: 'Email mittente', type: 'text', requiredOnCreate: true },
161
- { alias: 'subject', label: 'Oggetto', type: 'text', requiredOnCreate: true },
162
- { alias: 'message', label: 'Messaggio', type: 'richtext', requiredOnCreate: true },
163
- { alias: 'read', label: 'Letto', type: 'boolean' },
164
- ],
165
- };
166
- /** Registro: slug -> Seed */
167
- export const SEED_REGISTRY = {
168
- articoli: ARTICOLO_SEED,
169
- prodotti: PRODOTTO_SEED,
170
- team: TEAM_SEED,
171
- testimonianze: TESTIMONIANZA_SEED,
172
- pagine: PAGINA_SEED,
173
- clienti: CLIENTE_SEED,
174
- messaggi: MESSAGGI_SEED,
175
- };
176
- /** Ritorna il Seed per lo slug dato, o null se non esiste. */
177
17
  export function getSeed(slug) {
178
18
  return SEED_REGISTRY[slug] ?? null;
179
19
  }
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type BranchType = 'text' | 'number' | 'boolean' | 'json' | 'date' | 'richtext' | 'file';
1
+ export type BranchType = 'text' | 'number' | 'boolean' | 'json' | 'date' | 'richtext' | 'file' | 'tags';
2
2
  /** Branch: definizione di una proprietà. alias = nome colonna SQL. */
3
3
  export interface Branch {
4
4
  /** Alias human-readable, usato nel payload API e come nome colonna SQL nella tabella dedicata */
@@ -46,6 +46,26 @@ export interface Branch {
46
46
  public?: boolean;
47
47
  };
48
48
  }
49
+ /** Dashboard-specific config embedded in a Seed. All fields optional — defaults applied by the dashboard. */
50
+ export interface DashboardSeedConfig {
51
+ /** Lucide icon name (string, resolved to component client-side). Default: 'Folder' */
52
+ icon?: string;
53
+ /** Sidebar group label. Ungrouped seeds share a single 'Contents' section. */
54
+ group?: string;
55
+ /** Sort order within the group. Lower = higher. Default: 99 */
56
+ order?: number;
57
+ /** Hide from sidebar navigation. Default: false */
58
+ hidden?: boolean;
59
+ /** Tooltip description shown in the sidebar. */
60
+ description?: string;
61
+ /** UI feature toggles. All default to true unless specified. */
62
+ features?: {
63
+ search?: boolean;
64
+ filter?: boolean;
65
+ export?: boolean;
66
+ bulkDelete?: boolean;
67
+ };
68
+ }
49
69
  /** Seed: definizione dello schema di un tipo di contenuto */
50
70
  export interface Seed {
51
71
  /** Slug identificativo — anche nome tabella: `content_{slug}` */
@@ -73,9 +93,11 @@ export interface Seed {
73
93
  displayNameAlias: string;
74
94
  /** Lista dei campi (Branch) */
75
95
  branches: Branch[];
96
+ /** Optional dashboard-specific UI config. Ignored by the Botanical Engine. */
97
+ dashboard?: DashboardSeedConfig;
76
98
  }
77
- export type FilterOperator = 'eq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'is_empty' | 'is_not_empty';
78
- export type FilterType = 'text' | 'number' | 'date' | 'boolean' | 'tags' | 'select' | 'system';
99
+ export type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with' | 'is_empty' | 'is_not_empty' | 'in' | 'not_in' | 'has_tag' | 'has_any_tag' | 'has_all_tags';
100
+ export type FilterType = 'text' | 'number' | 'date' | 'boolean' | 'tags' | 'select' | 'system' | 'json';
79
101
  export interface FilterCondition {
80
102
  op: FilterOperator;
81
103
  value: string | number | boolean | null;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,IAAI,EAAE,MAAM,YAAY,CAAA;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC/B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAufD;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CA6G3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG,QAAQ,GAAG,WAAW,CAE9F;AAED;;;;;GAKG"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,IAAI,EAAE,MAAM,YAAY,CAAA;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC/B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AA6fD;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CA6G3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG,QAAQ,GAAG,WAAW,CAE9F;AAED;;;;;GAKG"}