@beechcms/core 0.4.1 → 0.4.3

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,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 {};
package/dist/index.d.ts CHANGED
@@ -37,4 +37,11 @@ export * from './content-scan.repository.js';
37
37
  export * from './clock.js';
38
38
  export * from './id-generator.js';
39
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';
40
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;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"}
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
@@ -37,3 +37,10 @@ export * from './content-scan.repository.js';
37
37
  export * from './clock.js';
38
38
  export * from './id-generator.js';
39
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,4 @@
1
+ export interface IScheduler {
2
+ waitUntil(promise: Promise<unknown>): void;
3
+ }
4
+ //# sourceMappingURL=scheduler.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.interface.d.ts","sourceRoot":"","sources":["../src/scheduler.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAC3C"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { IScheduler } from './scheduler.interface.js';
2
+ export declare class NoOpScheduler implements IScheduler {
3
+ waitUntil(_promise: Promise<unknown>): void;
4
+ }
5
+ //# sourceMappingURL=scheduler.stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.stub.d.ts","sourceRoot":"","sources":["../src/scheduler.stub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,qBAAa,aAAc,YAAW,UAAU;IAC9C,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;CAG5C"}
@@ -0,0 +1,5 @@
1
+ export class NoOpScheduler {
2
+ waitUntil(_promise) {
3
+ // intentionally empty
4
+ }
5
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"seed-registry.d.ts","sourceRoot":"","sources":["../src/seed-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,IAAI,IAAI,EAAE,CAAA;IAEb;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAE9B;;;;;OAKG;IACH,kBAAkB,IAAI,IAAI,EAAE,CAAA;IAE5B;;;OAGG;IACH,cAAc,IAAI,IAAI,EAAE,CAAA;IAExB;;;OAGG;IACH,YAAY,IAAI,IAAI,EAAE,CAAA;CACvB;AAED,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,KAAK,EAAE,IAAI,EAAE;IAKzB,GAAG,IAAI,IAAI,EAAE;IAIb,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI9B,kBAAkB,IAAI,IAAI,EAAE;IAI5B,cAAc,IAAI,IAAI,EAAE;IAIxB,YAAY,IAAI,IAAI,EAAE;CAGvB;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;CAAG"}
1
+ {"version":3,"file":"seed-registry.d.ts","sourceRoot":"","sources":["../src/seed-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAGtC,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,IAAI,IAAI,EAAE,CAAA;IAEb;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAE9B;;;;;OAKG;IACH,kBAAkB,IAAI,IAAI,EAAE,CAAA;IAE5B;;;OAGG;IACH,cAAc,IAAI,IAAI,EAAE,CAAA;IAExB;;;OAGG;IACH,YAAY,IAAI,IAAI,EAAE,CAAA;CACvB;AAED,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,KAAK,EAAE,IAAI,EAAE;IAezB,GAAG,IAAI,IAAI,EAAE;IAIb,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI9B,kBAAkB,IAAI,IAAI,EAAE;IAI5B,cAAc,IAAI,IAAI,EAAE;IAIxB,YAAY,IAAI,IAAI,EAAE;CAGvB;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;CAAG"}
@@ -1,7 +1,16 @@
1
+ import { AUTOMATION_RESERVED_WORDS } from './automations-grammar-words.js';
1
2
  export class SeedRegistry {
2
3
  seedMap;
3
4
  orderedSeeds;
4
5
  constructor(seeds) {
6
+ for (const seed of seeds) {
7
+ for (const branch of seed.branches) {
8
+ if (AUTOMATION_RESERVED_WORDS.has(branch.alias)) {
9
+ throw new Error(`Seed "${seed.slug}" uses reserved alias "${branch.alias}". `
10
+ + `Pick a different alias — this word is used by the automation template grammar.`);
11
+ }
12
+ }
13
+ }
5
14
  this.orderedSeeds = seeds;
6
15
  this.seedMap = new Map(seeds.map(seed => [seed.slug, seed]));
7
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slug-utils.d.ts","sourceRoot":"","sources":["../src/slug-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS7C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CASnG"}
1
+ {"version":3,"file":"slug-utils.d.ts","sourceRoot":"","sources":["../src/slug-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU7C;AAGD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CASnG"}
@@ -9,12 +9,13 @@
9
9
  export function slugify(value) {
10
10
  return value
11
11
  .normalize('NFKD') // Normalizza caratteri accentati
12
- .replace(/[^\w\s-]/g, '') // Rimuove tutto ciò che non è alfanumerico (accetta underscore temporaneamente)
12
+ .replace(/[^\w\s-]/g, '') // Rimuove tutto ciò che non è alfanumerico
13
13
  .trim()
14
14
  .toLowerCase()
15
- .replace(/[\s_-]+/g, '-') // Sostituisce spazi, underscore e trattini multipli con singolo trattino
15
+ .replace(/[\s_-]+/g, '-') // Sostituisce spazi e underscore con trattino
16
16
  .replace(/^-+|-+$/g, '') // Rimuove trattini all'inizio o alla fine
17
- .slice(0, 15); // Limita a 15 caratteri
17
+ .slice(0, 15) // Limita a 15 caratteri
18
+ .replace(/-+$/g, ''); // Rimuove trattini rimasti alla fine dopo il taglio
18
19
  }
19
20
  /**
20
21
  * Genera uno slug da un input (es. titolo o nome) o un fallback UUID.
package/dist/types.d.ts CHANGED
@@ -100,7 +100,7 @@ export type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'conta
100
100
  export type FilterType = 'text' | 'number' | 'date' | 'boolean' | 'tags' | 'select' | 'system' | 'json';
101
101
  export interface FilterCondition {
102
102
  op: FilterOperator;
103
- value: string | number | boolean | null;
103
+ value: string | number | boolean | null | string[] | number[];
104
104
  }
105
105
  export interface FilterGroup {
106
106
  /** Nome colonna: system column (id/slug/status/created_at/updated_at) o branch alias */
@@ -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;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"}
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;AAqaD;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CAmH3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG,QAAQ,GAAG,WAAW,CAE9F;AAED;;;;;GAKG"}
@@ -227,6 +227,7 @@ function requiredAliases(seed, operation) {
227
227
  }
228
228
  function buildBranchSchema(branch, options) {
229
229
  const nullable = options.allowNull ? z.null() : null;
230
+ const preprocessEmpty = (schema) => z.preprocess((val) => (val === '' || val === null ? (options.allowNull ? null : undefined) : val), schema.optional());
230
231
  switch (branch.type) {
231
232
  case 'text': {
232
233
  const schema = stringSchema
@@ -265,56 +266,48 @@ function buildBranchSchema(branch, options) {
265
266
  return nullable ? z.union([schema, nullable]) : schema;
266
267
  }
267
268
  case 'number': {
268
- const schema = finiteNumberSchema;
269
+ const schema = preprocessEmpty(finiteNumberSchema);
269
270
  return nullable ? z.union([schema, nullable]) : schema;
270
271
  }
271
272
  case 'boolean': {
272
- const schema = booleanSchema;
273
+ const schema = preprocessEmpty(booleanSchema);
273
274
  return nullable ? z.union([schema, nullable]) : schema;
274
275
  }
275
276
  case 'date': {
276
- const schema = stringSchema
277
+ const schema = preprocessEmpty(stringSchema
277
278
  .transform((value) => sanitizePlainString(value))
278
- .refine((value) => isIsoDateString(value), { message: 'Expected date(ISO)' });
279
+ .refine((value) => isIsoDateString(value), { message: 'Expected date(ISO)' }));
279
280
  return nullable ? z.union([schema, nullable]) : schema;
280
281
  }
281
282
  case 'json':
282
283
  case 'tags': {
283
- const schema = jsonObjectOrArraySchema;
284
+ const schema = preprocessEmpty(jsonObjectOrArraySchema);
284
285
  return nullable ? z.union([schema, nullable]) : schema;
285
286
  }
286
287
  case 'file': {
287
288
  if (isAssetListBranch(branch)) {
288
- const schema = z
289
- .any()
289
+ const schema = preprocessEmpty(z.any()
290
290
  .transform((rawValue, ctx) => {
291
291
  const normalized = normalizeAssetListValue(rawValue);
292
292
  if (!normalized) {
293
- ctx.addIssue({
294
- code: 'custom',
295
- message: 'Expected url-string[]',
296
- });
293
+ ctx.addIssue({ code: 'custom', message: 'Expected url-string[]' });
297
294
  return z.NEVER;
298
295
  }
299
296
  return normalized;
300
297
  })
301
- .pipe(z.array(z.url()));
298
+ .pipe(z.array(z.string().url())));
302
299
  return nullable ? z.union([schema, nullable]) : schema;
303
300
  }
304
- const schema = z
305
- .any()
301
+ const schema = preprocessEmpty(z.any()
306
302
  .transform((rawValue, ctx) => {
307
303
  const normalized = normalizeHttpUrl(rawValue);
308
304
  if (!normalized) {
309
- ctx.addIssue({
310
- code: 'custom',
311
- message: 'Expected url-string',
312
- });
305
+ ctx.addIssue({ code: 'custom', message: 'Expected url-string' });
313
306
  return z.NEVER;
314
307
  }
315
308
  return normalized;
316
309
  })
317
- .pipe(z.url());
310
+ .pipe(z.string().url()));
318
311
  return nullable ? z.union([schema, nullable]) : schema;
319
312
  }
320
313
  default:
@@ -371,85 +364,11 @@ function makeDetail(field, expected, received) {
371
364
  function isIsoDateString(value) {
372
365
  if (!/^\d{4}-\d{2}-\d{2}/.test(value))
373
366
  return false;
374
- return !Number.isNaN(Date.parse(value));
375
- }
376
- function validateBranchValue(branch, alias, rawValue, options) {
377
- if (rawValue === null) {
378
- return options.allowNull
379
- ? { ok: true, value: null }
380
- : { ok: false, detail: makeDetail(alias, branch.type, rawValue) };
381
- }
382
- switch (branch.type) {
383
- case 'text': {
384
- if (!stringSchema.safeParse(rawValue).success) {
385
- return { ok: false, detail: makeDetail(alias, 'string', rawValue) };
386
- }
387
- const sanitized = sanitizePlainString(rawValue);
388
- if (sanitized.length > options.maxTextLength) {
389
- return { ok: false, detail: makeDetail(alias, `string(max:${options.maxTextLength})`, rawValue) };
390
- }
391
- return { ok: true, value: sanitized };
392
- }
393
- case 'richtext': {
394
- const sanitized = sanitizeRichtext(rawValue);
395
- if (!sanitized.valid) {
396
- return { ok: false, detail: makeDetail(alias, 'richtext-json|string', rawValue) };
397
- }
398
- if (sanitized.size > options.maxTextLength) {
399
- return {
400
- ok: false,
401
- detail: makeDetail(alias, `richtext(max:${options.maxTextLength})`, rawValue),
402
- };
403
- }
404
- return { ok: true, value: sanitized.value, dangerous: sanitized.dangerous };
405
- }
406
- case 'number': {
407
- if (!finiteNumberSchema.safeParse(rawValue).success) {
408
- return { ok: false, detail: makeDetail(alias, 'number', rawValue) };
409
- }
410
- return { ok: true, value: rawValue };
411
- }
412
- case 'boolean': {
413
- if (!booleanSchema.safeParse(rawValue).success) {
414
- return { ok: false, detail: makeDetail(alias, 'boolean', rawValue) };
415
- }
416
- return { ok: true, value: rawValue };
417
- }
418
- case 'date': {
419
- if (!stringSchema.safeParse(rawValue).success) {
420
- return { ok: false, detail: makeDetail(alias, 'date(ISO)', rawValue) };
421
- }
422
- const value = sanitizePlainString(rawValue);
423
- if (!isIsoDateString(value)) {
424
- return { ok: false, detail: makeDetail(alias, 'date(ISO)', rawValue) };
425
- }
426
- return { ok: true, value };
427
- }
428
- case 'json':
429
- case 'tags': {
430
- const isValidJsonLike = (typeof rawValue === 'object' && rawValue !== null) || Array.isArray(rawValue);
431
- if (!isValidJsonLike || typeof rawValue === 'string') {
432
- return { ok: false, detail: makeDetail(alias, 'object|array', rawValue) };
433
- }
434
- return { ok: true, value: rawValue };
435
- }
436
- case 'file': {
437
- if (isAssetListBranch(branch)) {
438
- const listValue = normalizeAssetListValue(rawValue);
439
- if (!listValue) {
440
- return { ok: false, detail: makeDetail(alias, 'url-string[]', rawValue) };
441
- }
442
- return { ok: true, value: listValue };
443
- }
444
- const singleUrl = normalizeHttpUrl(rawValue);
445
- if (!singleUrl) {
446
- return { ok: false, detail: makeDetail(alias, 'url-string', rawValue) };
447
- }
448
- return { ok: true, value: singleUrl };
449
- }
450
- default:
451
- throw new Error(`Unhandled branch type: ${branch.type}`);
452
- }
367
+ const parsed = Date.parse(value);
368
+ if (Number.isNaN(parsed))
369
+ return false;
370
+ const d = new Date(parsed);
371
+ return d.toISOString().startsWith(value.substring(0, 10));
453
372
  }
454
373
  /**
455
374
  * Common foundation for schema-driven validation and sanitization of payloads.
@@ -508,6 +427,9 @@ export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
508
427
  }
509
428
  continue;
510
429
  }
430
+ if (issue.message === 'Required' && normalizedOptions.enforceRequiredFields) {
431
+ continue; // Let enforceRequiredFields logic below handle it properly with detailed messages
432
+ }
511
433
  const field = String(issue.path[0] ?? 'payload');
512
434
  const receivedValue = filteredPayload[field];
513
435
  const expected = typeof issue.message === 'string' && issue.message.startsWith('Expected ')
@@ -535,7 +457,8 @@ export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
535
457
  });
536
458
  continue;
537
459
  }
538
- if (isMissingRequiredValue(data[branch.alias])) {
460
+ const valueToCheck = parsed.success ? data[branch.alias] : filteredPayload[branch.alias];
461
+ if (isMissingRequiredValue(valueToCheck)) {
539
462
  requiredFieldsMissing.push(branch.alias);
540
463
  details.push({
541
464
  field: branch.alias,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beechcms/core",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",