@beechcms/core 0.4.0 → 0.4.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 (69) hide show
  1. package/dist/auth/password-reset-token.repository.d.ts +0 -1
  2. package/dist/auth/password-reset-token.repository.d.ts.map +1 -1
  3. package/dist/automations-grammar-words.d.ts +2 -0
  4. package/dist/automations-grammar-words.d.ts.map +1 -0
  5. package/dist/automations-grammar-words.js +6 -0
  6. package/dist/automations.repository.interface.d.ts +19 -0
  7. package/dist/automations.repository.interface.d.ts.map +1 -0
  8. package/dist/automations.repository.interface.js +1 -0
  9. package/dist/automations.runner.interface.d.ts +10 -0
  10. package/dist/automations.runner.interface.d.ts.map +1 -0
  11. package/dist/automations.runner.interface.js +1 -0
  12. package/dist/automations.runner.stub.d.ts +5 -0
  13. package/dist/automations.runner.stub.d.ts.map +1 -0
  14. package/dist/automations.runner.stub.js +5 -0
  15. package/dist/automations.types.d.ts +73 -0
  16. package/dist/automations.types.d.ts.map +1 -0
  17. package/dist/automations.types.js +1 -0
  18. package/dist/clock.d.ts +25 -0
  19. package/dist/clock.d.ts.map +1 -0
  20. package/dist/clock.js +9 -0
  21. package/dist/content-scan.repository.d.ts +9 -0
  22. package/dist/content-scan.repository.d.ts.map +1 -0
  23. package/dist/content-scan.repository.js +1 -0
  24. package/dist/engine.d.ts +24 -24
  25. package/dist/engine.js +22 -22
  26. package/dist/id-generator.d.ts +19 -0
  27. package/dist/id-generator.d.ts.map +1 -0
  28. package/dist/id-generator.js +7 -0
  29. package/dist/index.d.ts +27 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +27 -3
  32. package/dist/notifications/notification-service.d.ts +29 -0
  33. package/dist/notifications/notification-service.d.ts.map +1 -0
  34. package/dist/notifications/notification-service.js +1 -0
  35. package/dist/notifications/notification.repository.d.ts +51 -0
  36. package/dist/notifications/notification.repository.d.ts.map +1 -0
  37. package/dist/notifications/notification.repository.js +10 -0
  38. package/dist/observability/activity-log.repository.d.ts +58 -0
  39. package/dist/observability/activity-log.repository.d.ts.map +1 -0
  40. package/dist/observability/activity-log.repository.js +1 -0
  41. package/dist/observability/activity-logger.d.ts +49 -0
  42. package/dist/observability/activity-logger.d.ts.map +1 -0
  43. package/dist/observability/activity-logger.js +12 -0
  44. package/dist/observability/analytics.repository.d.ts +37 -0
  45. package/dist/observability/analytics.repository.d.ts.map +1 -0
  46. package/dist/observability/analytics.repository.js +1 -0
  47. package/dist/scheduler.interface.d.ts +4 -0
  48. package/dist/scheduler.interface.d.ts.map +1 -0
  49. package/dist/scheduler.interface.js +1 -0
  50. package/dist/scheduler.stub.d.ts +5 -0
  51. package/dist/scheduler.stub.d.ts.map +1 -0
  52. package/dist/scheduler.stub.js +5 -0
  53. package/dist/search/search.repository.d.ts +45 -0
  54. package/dist/search/search.repository.d.ts.map +1 -0
  55. package/dist/search/search.repository.js +1 -0
  56. package/dist/seed-registry.d.ts +49 -0
  57. package/dist/seed-registry.d.ts.map +1 -0
  58. package/dist/seed-registry.js +38 -0
  59. package/dist/slug-utils.d.ts.map +1 -1
  60. package/dist/slug-utils.js +4 -3
  61. package/dist/types.d.ts +1 -1
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/validation.d.ts +7 -7
  64. package/dist/validation.d.ts.map +1 -1
  65. package/dist/validation.js +29 -106
  66. package/dist/widget/widget.repository.d.ts +113 -0
  67. package/dist/widget/widget.repository.d.ts.map +1 -0
  68. package/dist/widget/widget.repository.js +1 -0
  69. package/package.json +9 -3
@@ -1,5 +1,4 @@
1
1
  export interface NewPasswordResetToken {
2
- id: string;
3
2
  userId: string;
4
3
  tokenHash: string;
5
4
  expiresAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"password-reset-token.repository.d.ts","sourceRoot":"","sources":["../../src/auth/password-reset-token.repository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtE,0FAA0F;IAC1F,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpD;;;;OAIG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtG,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/D"}
1
+ {"version":3,"file":"password-reset-token.repository.d.ts","sourceRoot":"","sources":["../../src/auth/password-reset-token.repository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtE,0FAA0F;IAC1F,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpD;;;;OAIG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtG,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/D"}
@@ -0,0 +1,2 @@
1
+ export declare const AUTOMATION_RESERVED_WORDS: Set<string>;
2
+ //# sourceMappingURL=automations-grammar-words.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations-grammar-words.d.ts","sourceRoot":"","sources":["../src/automations-grammar-words.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,aAKpC,CAAA"}
@@ -0,0 +1,6 @@
1
+ export const AUTOMATION_RESERVED_WORDS = new Set([
2
+ 'this', 'batch', 'all', 'firstone', 'lastone', 'byid', 'where',
3
+ 'array',
4
+ 'count', 'sum', 'avg', 'min', 'max', 'pluck',
5
+ 'true', 'false', 'null',
6
+ ]);
@@ -0,0 +1,19 @@
1
+ import type { Automation, AutomationAction, AutomationTrigger, AutomationTriggerEvent, WhenNode } from './automations.types.js';
2
+ export interface CreateAutomationInput {
3
+ seed_slug: string;
4
+ name: string;
5
+ triggers: AutomationTrigger[];
6
+ trigger_conditions: WhenNode | null;
7
+ actions: AutomationAction[];
8
+ }
9
+ export type UpdateAutomationInput = Partial<CreateAutomationInput>;
10
+ export interface IAutomationRepository {
11
+ list(seedSlug: string): Promise<Automation[]>;
12
+ findById(id: string): Promise<Automation | null>;
13
+ create(input: CreateAutomationInput): Promise<string>;
14
+ update(id: string, input: UpdateAutomationInput): Promise<void>;
15
+ toggle(id: string, enabled: boolean): Promise<void>;
16
+ delete(id: string): Promise<void>;
17
+ findActive(seedSlug: string, event: AutomationTriggerEvent): Promise<Automation[]>;
18
+ }
19
+ //# sourceMappingURL=automations.repository.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.repository.interface.d.ts","sourceRoot":"","sources":["../src/automations.repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAE/H,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,iBAAiB,EAAE,CAAA;IAC7B,kBAAkB,EAAE,QAAQ,GAAG,IAAI,CAAA;IACnC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAElE,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;CACnF"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { AutomationTriggerEvent } from './automations.types.js';
2
+ export interface AutomationEventPayload {
3
+ seedSlug: string;
4
+ event: AutomationTriggerEvent;
5
+ entry: Record<string, unknown>;
6
+ }
7
+ export interface IAutomationRunner {
8
+ run(payload: AutomationEventPayload): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=automations.runner.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.runner.interface.d.ts","sourceRoot":"","sources":["../src/automations.runner.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAEpE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,sBAAsB,CAAA;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { IAutomationRunner, AutomationEventPayload } from './automations.runner.interface.js';
2
+ export declare class NoOpAutomationRunner implements IAutomationRunner {
3
+ run(_payload: AutomationEventPayload): Promise<void>;
4
+ }
5
+ //# sourceMappingURL=automations.runner.stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.runner.stub.d.ts","sourceRoot":"","sources":["../src/automations.runner.stub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAElG,qBAAa,oBAAqB,YAAW,iBAAiB;IACtD,GAAG,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3D"}
@@ -0,0 +1,5 @@
1
+ export class NoOpAutomationRunner {
2
+ async run(_payload) {
3
+ // intentionally empty
4
+ }
5
+ }
@@ -0,0 +1,73 @@
1
+ export type AutomationTriggerEvent = 'create' | 'update' | 'delete' | 'cron';
2
+ export interface AutomationTrigger {
3
+ event: AutomationTriggerEvent;
4
+ cron?: string | null;
5
+ }
6
+ export interface TriggerCondition {
7
+ field: string;
8
+ op: 'eq' | 'neq' | 'contains' | 'gt' | 'lt' | 'isempty' | 'isnotempty';
9
+ value: unknown;
10
+ }
11
+ export type WhenOperand = {
12
+ kind: 'literal';
13
+ value: unknown;
14
+ } | {
15
+ kind: 'ref';
16
+ key: string;
17
+ };
18
+ export type WhenOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'startswith' | 'endswith' | 'in' | 'notin' | 'isempty' | 'isnotempty' | 'matches';
19
+ export interface WhenPredicate {
20
+ kind: 'predicate';
21
+ left: WhenOperand;
22
+ op: WhenOp;
23
+ right?: WhenOperand;
24
+ }
25
+ export interface WhenGroup {
26
+ kind: 'group';
27
+ op: 'AND' | 'OR';
28
+ children: WhenNode[];
29
+ negate?: boolean;
30
+ }
31
+ export type WhenNode = WhenPredicate | WhenGroup;
32
+ export interface SetVariableAction {
33
+ type: 'set_variable';
34
+ name: string;
35
+ seed_slug?: string;
36
+ fixed_id?: string;
37
+ column?: string;
38
+ filters?: TriggerCondition[];
39
+ order_by?: string;
40
+ order?: 'asc' | 'desc';
41
+ }
42
+ export type AutomationAction = {
43
+ type: 'webhook';
44
+ url: string;
45
+ method?: 'POST' | 'GET' | 'PUT';
46
+ headers?: Record<string, string>;
47
+ body_template?: string;
48
+ } | {
49
+ type: 'send_mail';
50
+ to: string;
51
+ subject_template: string;
52
+ body_template: string;
53
+ } | {
54
+ type: 'edit_field';
55
+ field: string;
56
+ value: unknown;
57
+ } | {
58
+ type: 'create_entry';
59
+ seed_slug: string;
60
+ field_map: Record<string, string>;
61
+ } | SetVariableAction;
62
+ export interface Automation {
63
+ id: string;
64
+ seed_slug: string;
65
+ name: string;
66
+ enabled: boolean;
67
+ triggers: AutomationTrigger[];
68
+ trigger_conditions: WhenNode | null;
69
+ actions: AutomationAction[];
70
+ created_at: number;
71
+ updated_at: number;
72
+ }
73
+ //# sourceMappingURL=automations.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.types.d.ts","sourceRoot":"","sources":["../src/automations.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Time abstraction. Hides direct calls to {@link Date.now} so callers can
3
+ * swap in deterministic clocks during tests without resorting to global
4
+ * timer mocks (e.g. vi.useFakeTimers, sinon, monkey-patching Date).
5
+ */
6
+ export interface IClock {
7
+ /**
8
+ * Returns the current Unix timestamp in milliseconds.
9
+ * Equivalent to Date.now() in production.
10
+ * Overridable in tests for deterministic time-sensitive assertions.
11
+ */
12
+ now(): number;
13
+ /**
14
+ * Returns the current Unix timestamp in whole seconds.
15
+ * Equivalent to Math.floor(Date.now() / 1000) in production.
16
+ * Used by JWT issuance, session expiry, and analytics day-bucket computations.
17
+ */
18
+ nowSeconds(): number;
19
+ }
20
+ /**
21
+ * Production singleton. Delegates to the host runtime clock. Stateless and
22
+ * therefore safe to share across requests.
23
+ */
24
+ export declare const SystemClock: IClock;
25
+ //# sourceMappingURL=clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,GAAG,IAAI,MAAM,CAAA;IAEb;;;;OAIG;IACH,UAAU,IAAI,MAAM,CAAA;CACrB;AAID;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAGzB,CAAA"}
package/dist/clock.js ADDED
@@ -0,0 +1,9 @@
1
+ const MILLISECONDS_PER_SECOND = 1000;
2
+ /**
3
+ * Production singleton. Delegates to the host runtime clock. Stateless and
4
+ * therefore safe to share across requests.
5
+ */
6
+ export const SystemClock = {
7
+ now: () => Date.now(),
8
+ nowSeconds: () => Math.floor(Date.now() / MILLISECONDS_PER_SECOND),
9
+ };
@@ -0,0 +1,9 @@
1
+ import type { Seed } from './types.js';
2
+ export interface IContentScanRepository {
3
+ /**
4
+ * Scans across all registered seeds to identify media keys that are currently referenced
5
+ * by any content entry. Used for orphaned media detection and storage analytics.
6
+ */
7
+ getReferencedMediaKeys(seeds: Seed[]): Promise<Set<string>>;
8
+ }
9
+ //# sourceMappingURL=content-scan.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-scan.repository.d.ts","sourceRoot":"","sources":["../src/content-scan.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;CAC5D"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/engine.d.ts CHANGED
@@ -1,47 +1,47 @@
1
1
  /**
2
2
  * Botanical Engine: Schema Compiler + Query Builder.
3
3
  *
4
- * In v0.4.0 ogni Seed ha una tabella SQL dedicata (`content_{slug}`) con colonne
5
- * reali tipizzate. Questo modulo genera il DDL e costruisce query parametrizzate.
6
- * Non conosce HTTP, auth o UI — è una libreria Node.js pura (C6).
4
+ * In v0.4.0 each Seed has a dedicated SQL table (`content_{slug}`) with
5
+ * real typed columns. This module generates the DDL and builds parameterized queries.
6
+ * It does not know about HTTP, auth, or UI — it's a pure TypeScript library.
7
7
  */
8
8
  import type { Seed, Branch, SelectOptions, ParameterizedQuery } from './types.js';
9
9
  /**
10
- * Genera `CREATE TABLE IF NOT EXISTS content_{slug}` con colonne di sistema
11
- * + una colonna per ogni Branch. Funzione pura: stesso Seed → stesso SQL.
10
+ * Generates `CREATE TABLE IF NOT EXISTS content_{slug}` with system columns
11
+ * + one column per Branch. Pure function: same Seed → same SQL.
12
12
  */
13
13
  export declare function generateCreateTable(seed: Seed): string;
14
14
  /**
15
- * Genera la tabella bozze `content_{slug}_drafts` per i Seed con `allowDrafts: true`.
16
- * Tutte le colonne branch sono nullable (le bozze sono parziali).
17
- * Ritorna null se il Seed non ha `allowDrafts: true`.
15
+ * Generates the drafts table `content_{slug}_drafts` for Seeds with `allowDrafts: true`.
16
+ * All branch columns are nullable (drafts are partial).
17
+ * Returns null if the Seed does not have `allowDrafts: true`.
18
18
  */
19
19
  export declare function generateDraftTable(seed: Seed): string | null;
20
20
  /**
21
- * Genera `ALTER TABLE content_{slug} ADD COLUMN {alias} {type}`.
22
- * Nuove colonne sono sempre nullable (limite SQLite su ALTER TABLE).
21
+ * Generates `ALTER TABLE content_{slug} ADD COLUMN {alias} {type}`.
22
+ * New columns are always nullable (SQLite limit on ALTER TABLE).
23
23
  */
24
24
  export declare function generateAddColumn(seed: Seed, branch: Branch): string;
25
25
  /**
26
- * Genera indici B-tree per status, created_at e ogni Branch filtrabile
27
- * con tipo indicizzabile (text, number, date, boolean).
26
+ * Generates B-tree indexes for status, created_at and every filterable Branch
27
+ * with an indexable type (text, number, date, boolean).
28
28
  */
29
29
  export declare function generateIndexes(seed: Seed): string[];
30
30
  /**
31
- * Genera la virtual table FTS5 per i Branch text/richtext indicizzabili.
32
- * Ritorna null se il Seed non ha branch con search abilitato.
31
+ * Generates the FTS5 virtual table for indexable text/richtext Branches.
32
+ * Returns null if the Seed has no branches with search enabled.
33
33
  */
34
34
  export declare function generateFtsTable(seed: Seed): string | null;
35
35
  /**
36
- * Genera i 3 trigger SQLite (insert/update/delete) che mantengono la FTS
37
- * sincronizzata automaticamenteelimina la necessità di syncFts manuale.
38
- * Ritorna array vuoto se il Seed non ha branch indicizzabili.
36
+ * Generates the 3 SQLite triggers (insert/update/delete) that keep the FTS
37
+ * automatically synchronizedeliminates the need for manual syncFts.
38
+ * Returns an empty array if the Seed has no indexable branches.
39
39
  */
40
40
  export declare function generateFtsTriggers(seed: Seed): string[];
41
41
  /**
42
- * Costruisce una SELECT parametrizzata su `content_{slug}`.
43
- * Non usa mai json_extract — ogni colonna è una colonna reale.
44
- * Colonne sconosciute nei filtri/orderBy vengono ignorate (fail-closed).
42
+ * Builds a parameterized SELECT on `content_{slug}`.
43
+ * Never uses json_extract — every column is a real column.
44
+ * Unknown columns in filters/orderBy are ignored (fail-closed).
45
45
  */
46
46
  export declare function buildSelectQuery(seed: Seed, options?: SelectOptions): ParameterizedQuery;
47
47
  export interface SchemaColumn {
@@ -51,17 +51,17 @@ export interface SchemaColumn {
51
51
  isPk: boolean;
52
52
  }
53
53
  /**
54
- * Ritorna la lista di colonne attese per la tabella di un Seed.
55
- * Usato da `beech seed:load --diff` per confrontare schema attuale vs atteso.
54
+ * Returns the list of expected columns for a Seed's table.
55
+ * Used by `beech seed:load --diff` to compare current vs expected schema.
56
56
  */
57
57
  export declare function getExpectedColumns(seed: Seed): SchemaColumn[];
58
58
  /**
59
- * Serializza un valore per la scrittura nel DB.
59
+ * Serializes a value for writing to the DB.
60
60
  * boolean → 0/1 | date → Unix timestamp | json/asset-list → JSON string
61
61
  */
62
62
  export declare function serializeForDb(branch: Branch, value: unknown): string | number | null;
63
63
  /**
64
- * Deserializza un valore letto dal DB per la risposta API.
64
+ * Deserializes a value read from the DB for the API response.
65
65
  * 0/1 → boolean | Unix timestamp → ISO 8601 | JSON string → object
66
66
  */
67
67
  export declare function deserializeFromDb(branch: Branch, value: unknown): unknown;
package/dist/engine.js CHANGED
@@ -71,8 +71,8 @@ function normalizeAssetListValue(rawValue) {
71
71
  }
72
72
  // ---- DDL Generators ----
73
73
  /**
74
- * Genera `CREATE TABLE IF NOT EXISTS content_{slug}` con colonne di sistema
75
- * + una colonna per ogni Branch. Funzione pura: stesso Seed → stesso SQL.
74
+ * Generates `CREATE TABLE IF NOT EXISTS content_{slug}` with system columns
75
+ * + one column per Branch. Pure function: same Seed → same SQL.
76
76
  */
77
77
  export function generateCreateTable(seed) {
78
78
  const table = tableName(seed);
@@ -97,9 +97,9 @@ export function generateCreateTable(seed) {
97
97
  return lines.join('\n');
98
98
  }
99
99
  /**
100
- * Genera la tabella bozze `content_{slug}_drafts` per i Seed con `allowDrafts: true`.
101
- * Tutte le colonne branch sono nullable (le bozze sono parziali).
102
- * Ritorna null se il Seed non ha `allowDrafts: true`.
100
+ * Generates the drafts table `content_{slug}_drafts` for Seeds with `allowDrafts: true`.
101
+ * All branch columns are nullable (drafts are partial).
102
+ * Returns null if the Seed does not have `allowDrafts: true`.
103
103
  */
104
104
  export function generateDraftTable(seed) {
105
105
  if (!seed.allowDrafts)
@@ -114,7 +114,7 @@ export function generateDraftTable(seed) {
114
114
  for (const branch of seed.branches) {
115
115
  const { sqlType } = BRANCH_TYPE_SQL[branch.type];
116
116
  let col = ` ${branch.alias} ${sqlType}`;
117
- // boolean CHECK: in SQLite, NULL IN (0,1) → NULL, che passa il CHECK (solo FALSE lo fallisce)
117
+ // boolean CHECK: in SQLite, NULL IN (0,1) → NULL, which passes the CHECK (only FALSE fails it)
118
118
  if (branch.type === 'boolean')
119
119
  col += ` CHECK (${branch.alias} IN (0, 1))`;
120
120
  lines.push(col + ',');
@@ -124,16 +124,16 @@ export function generateDraftTable(seed) {
124
124
  return lines.join('\n');
125
125
  }
126
126
  /**
127
- * Genera `ALTER TABLE content_{slug} ADD COLUMN {alias} {type}`.
128
- * Nuove colonne sono sempre nullable (limite SQLite su ALTER TABLE).
127
+ * Generates `ALTER TABLE content_{slug} ADD COLUMN {alias} {type}`.
128
+ * New columns are always nullable (SQLite limit on ALTER TABLE).
129
129
  */
130
130
  export function generateAddColumn(seed, branch) {
131
131
  const { sqlType } = BRANCH_TYPE_SQL[branch.type];
132
132
  return `ALTER TABLE ${tableName(seed)} ADD COLUMN ${branch.alias} ${sqlType};`;
133
133
  }
134
134
  /**
135
- * Genera indici B-tree per status, created_at e ogni Branch filtrabile
136
- * con tipo indicizzabile (text, number, date, boolean).
135
+ * Generates B-tree indexes for status, created_at and every filterable Branch
136
+ * with an indexable type (text, number, date, boolean).
137
137
  */
138
138
  export function generateIndexes(seed) {
139
139
  const table = tableName(seed);
@@ -152,8 +152,8 @@ export function generateIndexes(seed) {
152
152
  return indexes;
153
153
  }
154
154
  /**
155
- * Genera la virtual table FTS5 per i Branch text/richtext indicizzabili.
156
- * Ritorna null se il Seed non ha branch con search abilitato.
155
+ * Generates the FTS5 virtual table for indexable text/richtext Branches.
156
+ * Returns null if the Seed has no branches with search enabled.
157
157
  */
158
158
  export function generateFtsTable(seed) {
159
159
  const rtBranches = indexableSearchBranches(seed);
@@ -170,9 +170,9 @@ export function generateFtsTable(seed) {
170
170
  ].join('\n');
171
171
  }
172
172
  /**
173
- * Genera i 3 trigger SQLite (insert/update/delete) che mantengono la FTS
174
- * sincronizzata automaticamenteelimina la necessità di syncFts manuale.
175
- * Ritorna array vuoto se il Seed non ha branch indicizzabili.
173
+ * Generates the 3 SQLite triggers (insert/update/delete) that keep the FTS
174
+ * automatically synchronizedeliminates the need for manual syncFts.
175
+ * Returns an empty array if the Seed has no indexable branches.
176
176
  */
177
177
  export function generateFtsTriggers(seed) {
178
178
  const rtBranches = indexableSearchBranches(seed);
@@ -208,9 +208,9 @@ export function generateFtsTriggers(seed) {
208
208
  }
209
209
  // ---- Query Builder ----
210
210
  /**
211
- * Costruisce una SELECT parametrizzata su `content_{slug}`.
212
- * Non usa mai json_extract — ogni colonna è una colonna reale.
213
- * Colonne sconosciute nei filtri/orderBy vengono ignorate (fail-closed).
211
+ * Builds a parameterized SELECT on `content_{slug}`.
212
+ * Never uses json_extract — every column is a real column.
213
+ * Unknown columns in filters/orderBy are ignored (fail-closed).
214
214
  */
215
215
  export function buildSelectQuery(seed, options = {}) {
216
216
  const table = tableName(seed);
@@ -369,8 +369,8 @@ function buildFilterCondition(col, type, cond, bindings) {
369
369
  return null;
370
370
  }
371
371
  /**
372
- * Ritorna la lista di colonne attese per la tabella di un Seed.
373
- * Usato da `beech seed:load --diff` per confrontare schema attuale vs atteso.
372
+ * Returns the list of expected columns for a Seed's table.
373
+ * Used by `beech seed:load --diff` to compare current vs expected schema.
374
374
  */
375
375
  export function getExpectedColumns(seed) {
376
376
  return [
@@ -389,7 +389,7 @@ export function getExpectedColumns(seed) {
389
389
  }
390
390
  // ---- Serialization / Deserialization ----
391
391
  /**
392
- * Serializza un valore per la scrittura nel DB.
392
+ * Serializes a value for writing to the DB.
393
393
  * boolean → 0/1 | date → Unix timestamp | json/asset-list → JSON string
394
394
  */
395
395
  export function serializeForDb(branch, value) {
@@ -427,7 +427,7 @@ export function serializeForDb(branch, value) {
427
427
  }
428
428
  }
429
429
  /**
430
- * Deserializza un valore letto dal DB per la risposta API.
430
+ * Deserializes a value read from the DB for the API response.
431
431
  * 0/1 → boolean | Unix timestamp → ISO 8601 | JSON string → object
432
432
  */
433
433
  export function deserializeFromDb(branch, value) {
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Identifier abstraction. Hides direct calls to {@link crypto.randomUUID}
3
+ * so callers can swap in deterministic generators during tests for stable
4
+ * snapshot assertions and predictable insert ordering.
5
+ */
6
+ export interface IIdGenerator {
7
+ /**
8
+ * Generates a new universally unique identifier.
9
+ * Production implementation delegates to crypto.randomUUID().
10
+ * Test implementations return deterministic values for snapshot assertions.
11
+ */
12
+ uuid(): string;
13
+ }
14
+ /**
15
+ * Production singleton. Delegates to the host runtime CSPRNG-backed UUID
16
+ * generator. Stateless and therefore safe to share across requests.
17
+ */
18
+ export declare const SystemIdGenerator: IIdGenerator;
19
+ //# sourceMappingURL=id-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-generator.d.ts","sourceRoot":"","sources":["../src/id-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,IAAI,IAAI,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAE/B,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Production singleton. Delegates to the host runtime CSPRNG-backed UUID
3
+ * generator. Stateless and therefore safe to share across requests.
4
+ */
5
+ export const SystemIdGenerator = {
6
+ uuid: () => crypto.randomUUID(),
7
+ };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * @beechcms/core - Botanical Engine
3
3
  *
4
- * Pacchetto condiviso del monorepo Beech CMS.
5
- * In v0.4.0 il Botanical Engine è un compilatore di schema SQL: legge i Seed
6
- * TypeScript e genera DDL deterministico + query parametrizzate.
4
+ * Shared package of the Beech CMS monorepo.
5
+ * In v0.4.0 the Botanical Engine is a SQL schema compiler: it reads TypeScript
6
+ * Seeds and generates deterministic DDL + parameterized queries.
7
7
  *
8
8
  * @module @beechcms/core
9
9
  */
@@ -20,4 +20,28 @@ export * from './idempotency.repository.js';
20
20
  export * from './media.repository.js';
21
21
  export * from './storage.js';
22
22
  export * from './policies.js';
23
+ export * from './auth/hash-provider.js';
24
+ export * from './auth/token-service.js';
25
+ export * from './auth/user.repository.js';
26
+ export * from './auth/session.repository.js';
27
+ export * from './auth/password-reset-token.repository.js';
28
+ export * from './rate-limit/rate-limiter.js';
29
+ export * from './observability/activity-logger.js';
30
+ export * from './observability/activity-log.repository.js';
31
+ export * from './observability/analytics.repository.js';
32
+ export * from './notifications/notification.repository.js';
33
+ export * from './notifications/notification-service.js';
34
+ export * from './widget/widget.repository.js';
35
+ export * from './search/search.repository.js';
36
+ export * from './content-scan.repository.js';
37
+ export * from './clock.js';
38
+ export * from './id-generator.js';
39
+ export * from './seed-registry.js';
40
+ export * from './automations.types.js';
41
+ export * from './automations-grammar-words.js';
42
+ export * from './automations.runner.interface.js';
43
+ export * from './automations.repository.interface.js';
44
+ export * from './automations.runner.stub.js';
45
+ export * from './scheduler.interface.js';
46
+ export * from './scheduler.stub.js';
23
47
  //# 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,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,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,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2CAA2C,CAAA;AACzD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oCAAoC,CAAA;AAClD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,yCAAyC,CAAA;AACvD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,mCAAmC,CAAA;AACjD,cAAc,uCAAuC,CAAA;AACrD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * @beechcms/core - Botanical Engine
3
3
  *
4
- * Pacchetto condiviso del monorepo Beech CMS.
5
- * In v0.4.0 il Botanical Engine è un compilatore di schema SQL: legge i Seed
6
- * TypeScript e genera DDL deterministico + query parametrizzate.
4
+ * Shared package of the Beech CMS monorepo.
5
+ * In v0.4.0 the Botanical Engine is a SQL schema compiler: it reads TypeScript
6
+ * Seeds and generates deterministic DDL + parameterized queries.
7
7
  *
8
8
  * @module @beechcms/core
9
9
  */
@@ -20,3 +20,27 @@ export * from './idempotency.repository.js';
20
20
  export * from './media.repository.js';
21
21
  export * from './storage.js';
22
22
  export * from './policies.js';
23
+ export * from './auth/hash-provider.js';
24
+ export * from './auth/token-service.js';
25
+ export * from './auth/user.repository.js';
26
+ export * from './auth/session.repository.js';
27
+ export * from './auth/password-reset-token.repository.js';
28
+ export * from './rate-limit/rate-limiter.js';
29
+ export * from './observability/activity-logger.js';
30
+ export * from './observability/activity-log.repository.js';
31
+ export * from './observability/analytics.repository.js';
32
+ export * from './notifications/notification.repository.js';
33
+ export * from './notifications/notification-service.js';
34
+ export * from './widget/widget.repository.js';
35
+ export * from './search/search.repository.js';
36
+ export * from './content-scan.repository.js';
37
+ export * from './clock.js';
38
+ export * from './id-generator.js';
39
+ export * from './seed-registry.js';
40
+ export * from './automations.types.js';
41
+ export * from './automations-grammar-words.js';
42
+ export * from './automations.runner.interface.js';
43
+ export * from './automations.repository.interface.js';
44
+ export * from './automations.runner.stub.js';
45
+ export * from './scheduler.interface.js';
46
+ export * from './scheduler.stub.js';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Notification service contract.
3
+ *
4
+ * High-level port that callers use to emit a notification without knowing
5
+ * about the underlying repository, the database, or background scheduling.
6
+ * Mirrors the email module pattern: handlers depend on the service, the
7
+ * service depends on the repository, the repository depends on D1.
8
+ *
9
+ * @module @beechcms/core/notifications/notification-service
10
+ */
11
+ import type { NotificationType } from './notification.repository.js';
12
+ export interface CreateNotificationInput {
13
+ title: string;
14
+ message: string;
15
+ type?: NotificationType;
16
+ }
17
+ export interface INotificationService {
18
+ /**
19
+ * Emit a notification.
20
+ *
21
+ * Implementations decide whether to fire-and-forget (production: schedules
22
+ * the underlying repository write through `executionCtx.waitUntil`) or to
23
+ * wait inline (tests). Like the activity logger, this method MUST NOT
24
+ * throw to the caller: a failed notification must never break the public
25
+ * request that triggered it.
26
+ */
27
+ notify(input: CreateNotificationInput): Promise<void> | void;
28
+ }
29
+ //# sourceMappingURL=notification-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-service.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAEpE,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC7D"}
@@ -0,0 +1 @@
1
+ export {};