node-type-registry 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/blueprint-types.generated.d.ts +46 -1
  2. package/codegen/generate-types.js +37 -1
  3. package/conditions/index.d.ts +1 -0
  4. package/conditions/index.js +8 -0
  5. package/conditions/trigger-condition.d.ts +35 -0
  6. package/conditions/trigger-condition.js +97 -0
  7. package/data/data-aggregate-limit-counter.d.ts +1 -1
  8. package/data/data-aggregate-limit-counter.js +7 -7
  9. package/data/data-billing-meter.d.ts +1 -1
  10. package/data/data-billing-meter.js +7 -7
  11. package/data/data-chunks.js +20 -0
  12. package/data/data-composite-field.js +4 -2
  13. package/data/data-direct-owner.js +5 -0
  14. package/data/data-entity-membership.js +5 -0
  15. package/data/data-feature-flag.d.ts +1 -1
  16. package/data/data-feature-flag.js +7 -7
  17. package/data/data-file-embedding.js +23 -10
  18. package/data/data-image-embedding.js +15 -9
  19. package/data/data-job-trigger.js +3 -53
  20. package/data/data-jsonb.js +2 -1
  21. package/data/data-limit-counter.d.ts +1 -1
  22. package/data/data-limit-counter.js +7 -7
  23. package/data/data-meter-rate-limit.d.ts +2 -0
  24. package/data/data-meter-rate-limit.js +42 -0
  25. package/data/data-ownership-in-entity.js +5 -0
  26. package/data/data-peoplestamps.js +5 -0
  27. package/data/data-publishable.js +2 -2
  28. package/data/data-slug.js +3 -4
  29. package/data/data-tags.js +2 -1
  30. package/data/event-tracker.d.ts +2 -0
  31. package/data/event-tracker.js +74 -0
  32. package/data/index.d.ts +9 -4
  33. package/data/index.js +15 -5
  34. package/data/limit-warning-aggregate.d.ts +2 -0
  35. package/data/limit-warning-aggregate.js +27 -0
  36. package/data/limit-warning-counter.d.ts +2 -0
  37. package/data/limit-warning-counter.js +33 -0
  38. package/data/limit-warning-rate.d.ts +2 -0
  39. package/data/limit-warning-rate.js +33 -0
  40. package/data/process-extraction.js +15 -10
  41. package/data/process-image-versions.js +3 -9
  42. package/data/search-unified.js +20 -0
  43. package/data/search-vector.js +12 -0
  44. package/esm/blueprint-types.generated.d.ts +46 -1
  45. package/esm/codegen/generate-types.js +37 -1
  46. package/esm/conditions/index.d.ts +1 -0
  47. package/esm/conditions/index.js +1 -0
  48. package/esm/conditions/trigger-condition.d.ts +35 -0
  49. package/esm/conditions/trigger-condition.js +94 -0
  50. package/esm/data/data-aggregate-limit-counter.d.ts +1 -1
  51. package/esm/data/data-aggregate-limit-counter.js +6 -6
  52. package/esm/data/data-billing-meter.d.ts +1 -1
  53. package/esm/data/data-billing-meter.js +6 -6
  54. package/esm/data/data-chunks.js +20 -0
  55. package/esm/data/data-composite-field.js +4 -2
  56. package/esm/data/data-direct-owner.js +5 -0
  57. package/esm/data/data-entity-membership.js +5 -0
  58. package/esm/data/data-feature-flag.d.ts +1 -1
  59. package/esm/data/data-feature-flag.js +6 -6
  60. package/esm/data/data-file-embedding.js +23 -10
  61. package/esm/data/data-image-embedding.js +15 -9
  62. package/esm/data/data-job-trigger.js +3 -53
  63. package/esm/data/data-jsonb.js +2 -1
  64. package/esm/data/data-limit-counter.d.ts +1 -1
  65. package/esm/data/data-limit-counter.js +6 -6
  66. package/esm/data/data-meter-rate-limit.d.ts +2 -0
  67. package/esm/data/data-meter-rate-limit.js +39 -0
  68. package/esm/data/data-ownership-in-entity.js +5 -0
  69. package/esm/data/data-peoplestamps.js +5 -0
  70. package/esm/data/data-publishable.js +2 -2
  71. package/esm/data/data-slug.js +3 -4
  72. package/esm/data/data-tags.js +2 -1
  73. package/esm/data/event-tracker.d.ts +2 -0
  74. package/esm/data/event-tracker.js +71 -0
  75. package/esm/data/index.d.ts +9 -4
  76. package/esm/data/index.js +9 -4
  77. package/esm/data/limit-warning-aggregate.d.ts +2 -0
  78. package/esm/data/limit-warning-aggregate.js +24 -0
  79. package/esm/data/limit-warning-counter.d.ts +2 -0
  80. package/esm/data/limit-warning-counter.js +30 -0
  81. package/esm/data/limit-warning-rate.d.ts +2 -0
  82. package/esm/data/limit-warning-rate.js +30 -0
  83. package/esm/data/process-extraction.js +15 -10
  84. package/esm/data/process-image-versions.js +3 -9
  85. package/esm/data/search-unified.js +20 -0
  86. package/esm/data/search-vector.js +12 -0
  87. package/esm/index.d.ts +1 -0
  88. package/esm/index.js +1 -0
  89. package/index.d.ts +1 -0
  90. package/index.js +1 -0
  91. package/package.json +2 -2
@@ -1,28 +1,4 @@
1
- const triggerConditionSchema = {
2
- type: 'object',
3
- description: 'A leaf condition ({field, op, value?, row?, ref?}) or a combinator ({AND, OR, NOT}).',
4
- properties: {
5
- field: { type: 'string', format: 'column-ref', description: 'Column name (validated against the table).' },
6
- op: {
7
- type: 'string',
8
- enum: ['=', '!=', '>', '<', '>=', '<=', 'LIKE', 'NOT LIKE', 'IS NULL', 'IS NOT NULL', 'IS DISTINCT FROM'],
9
- description: 'Comparison operator.'
10
- },
11
- value: { description: 'Comparison value. Type is resolved from the column definition. Omit for IS NULL, IS NOT NULL, IS DISTINCT FROM.' },
12
- row: { type: 'string', enum: ['NEW', 'OLD'], default: 'NEW', description: 'Row reference (default: NEW).' },
13
- ref: {
14
- type: 'object',
15
- description: 'Column reference for field-to-field comparison (alternative to value).',
16
- properties: {
17
- field: { type: 'string', format: 'column-ref' },
18
- row: { type: 'string', enum: ['NEW', 'OLD'], default: 'NEW' }
19
- }
20
- },
21
- AND: { type: 'array', description: 'Array of conditions combined with AND.', items: { $ref: '#/$defs/triggerCondition' } },
22
- OR: { type: 'array', description: 'Array of conditions combined with OR.', items: { $ref: '#/$defs/triggerCondition' } },
23
- NOT: { $ref: '#/$defs/triggerCondition', description: 'Negated condition.' }
24
- }
25
- };
1
+ import { conditionDefs, conditionProperties } from '../conditions';
26
2
  export const JobTrigger = {
27
3
  name: 'JobTrigger',
28
4
  slug: 'data_job_trigger',
@@ -31,9 +7,7 @@ export const JobTrigger = {
31
7
  description: 'Dynamically creates PostgreSQL triggers that enqueue jobs via app_jobs.add_job() when table rows are inserted, updated, or deleted. Supports configurable payload strategies (full row, row ID, selected fields, or custom mapping), conditional firing via WHEN clauses, watched field changes, and extended job options (queue, priority, delay, max attempts).',
32
8
  parameter_schema: {
33
9
  type: 'object',
34
- $defs: {
35
- triggerCondition: triggerConditionSchema
36
- },
10
+ $defs: conditionDefs,
37
11
  properties: {
38
12
  task_identifier: {
39
13
  type: 'string',
@@ -92,31 +66,7 @@ export const JobTrigger = {
92
66
  description: 'Include table/schema metadata in payload',
93
67
  default: false
94
68
  },
95
- condition_field: {
96
- type: 'string',
97
- format: 'column-ref',
98
- description: 'Column name for conditional WHEN clause (fires only when field equals condition_value)'
99
- },
100
- condition_value: {
101
- type: 'string',
102
- description: 'Value to compare against condition_field in WHEN clause'
103
- },
104
- conditions: {
105
- description: 'Compound conditions for the trigger WHEN clause. Accepts a single leaf condition, an array of conditions (implicitly AND), or a nested combinator tree ({AND: [...], OR: [...], NOT: {...}}). Each leaf is {field, op, value?, row?, ref?}. Column types are resolved automatically from the table schema. Cannot be combined with condition_field or watch_fields.',
106
- 'x-codegen-type': 'TriggerCondition | TriggerCondition[]',
107
- oneOf: [
108
- { $ref: '#/$defs/triggerCondition' },
109
- { type: 'array', items: { $ref: '#/$defs/triggerCondition' } }
110
- ]
111
- },
112
- watch_fields: {
113
- type: 'array',
114
- items: {
115
- type: 'string',
116
- format: 'column-ref'
117
- },
118
- description: 'For UPDATE triggers, only fire when these fields change (uses DISTINCT FROM)'
119
- },
69
+ ...conditionProperties,
120
70
  job_key: {
121
71
  type: 'string',
122
72
  description: 'Static job key for upsert semantics (prevents duplicate jobs)'
@@ -15,7 +15,8 @@ export const DataJsonb = {
15
15
  },
16
16
  default_value: {
17
17
  type: 'string',
18
- description: 'Default value expression'
18
+ description: 'Default value expression',
19
+ default: "'{}'::jsonb"
19
20
  },
20
21
  is_required: {
21
22
  type: 'boolean',
@@ -1,2 +1,2 @@
1
1
  import type { NodeTypeDefinition } from '../types';
2
- export declare const LimitCounter: NodeTypeDefinition;
2
+ export declare const LimitEnforceCounter: NodeTypeDefinition;
@@ -1,8 +1,8 @@
1
- export const LimitCounter = {
2
- name: 'LimitCounter',
3
- slug: 'data_limit_counter',
4
- category: 'limit',
5
- display_name: 'Limit Counter',
1
+ export const LimitEnforceCounter = {
2
+ name: 'LimitEnforceCounter',
3
+ slug: 'limit_enforce_counter',
4
+ category: 'limit_enforce',
5
+ display_name: 'Enforce Counter',
6
6
  description: 'Declaratively attaches limit-tracking triggers to a table. On INSERT the named limit is incremented; on DELETE it is decremented. Requires a provisioned limits_module for the target scope.',
7
7
  parameter_schema: {
8
8
  type: 'object',
@@ -35,5 +35,5 @@ export const LimitCounter = {
35
35
  },
36
36
  required: ['limit_name'],
37
37
  },
38
- tags: ['limits', 'triggers', 'billing'],
38
+ tags: ['limits', 'triggers', 'enforce'],
39
39
  };
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const LimitEnforceRate: NodeTypeDefinition;
@@ -0,0 +1,39 @@
1
+ export const LimitEnforceRate = {
2
+ name: 'LimitEnforceRate',
3
+ slug: 'limit_enforce_rate',
4
+ category: 'limit_enforce',
5
+ display_name: 'Enforce Rate Limit',
6
+ description: 'Attaches a BEFORE trigger that calls check_rate_limit() to enforce sliding-window rate limits before allowing mutations. The function checks all three scopes (entity, actor-in-entity, actor) in a single call; which scopes are actually enforced is controlled by what rows exist in rate_window_limits (plan-based config). Requires a provisioned meter_rate_limits_module and billing_module for the target database.',
7
+ parameter_schema: {
8
+ type: 'object',
9
+ properties: {
10
+ meter_slug: {
11
+ type: 'string',
12
+ description: 'Slug of the billing meter to check rate limits against (must match a meters table entry, e.g. "messaging", "inference")',
13
+ },
14
+ entity_field: {
15
+ type: 'string',
16
+ format: 'column-ref',
17
+ description: 'Column on the target table that holds the entity id (org) for rate limiting',
18
+ default: 'entity_id',
19
+ },
20
+ actor_field: {
21
+ type: 'string',
22
+ format: 'column-ref',
23
+ description: 'Column on the target table that holds the actor id (user) for rate limiting',
24
+ default: 'owner_id',
25
+ },
26
+ events: {
27
+ type: 'array',
28
+ items: {
29
+ type: 'string',
30
+ enum: ['INSERT', 'UPDATE'],
31
+ },
32
+ description: 'Which DML events to enforce rate limits on (DELETE is excluded since it reduces load)',
33
+ default: ['INSERT'],
34
+ },
35
+ },
36
+ required: ['meter_slug'],
37
+ },
38
+ tags: ['rate-limits', 'triggers', 'enforce', 'metering', 'abuse-protection'],
39
+ };
@@ -28,6 +28,11 @@ export const DataOwnershipInEntity = {
28
28
  type: 'boolean',
29
29
  description: 'If true, adds foreign key constraints from owner_id and entity_id to the users table',
30
30
  default: true
31
+ },
32
+ create_index: {
33
+ type: 'boolean',
34
+ description: 'If true, creates B-tree indexes on the owner and entity columns',
35
+ default: true
31
36
  }
32
37
  }
33
38
  },
@@ -28,6 +28,11 @@ export const DataPeoplestamps = {
28
28
  type: 'boolean',
29
29
  description: 'If true, adds foreign key constraints from created_by and updated_by to the users table',
30
30
  default: false
31
+ },
32
+ create_index: {
33
+ type: 'boolean',
34
+ description: 'If true, creates B-tree indexes on the peoplestamp columns',
35
+ default: true
31
36
  }
32
37
  }
33
38
  },
@@ -7,13 +7,13 @@ export const DataPublishable = {
7
7
  parameter_schema: {
8
8
  type: 'object',
9
9
  properties: {
10
- is_published_field: {
10
+ is_published_field_name: {
11
11
  type: 'string',
12
12
  format: 'column-ref',
13
13
  description: 'Column name for the published boolean flag',
14
14
  default: 'is_published'
15
15
  },
16
- published_at_field: {
16
+ published_at_field_name: {
17
17
  type: 'string',
18
18
  format: 'column-ref',
19
19
  description: 'Column name for the publish timestamp',
@@ -10,7 +10,8 @@ export const DataSlug = {
10
10
  field_name: {
11
11
  type: 'string',
12
12
  format: 'column-ref',
13
- description: 'Name of the field to slugify'
13
+ description: 'Name of the field to slugify',
14
+ default: 'slug'
14
15
  },
15
16
  source_field_name: {
16
17
  type: 'string',
@@ -18,9 +19,7 @@ export const DataSlug = {
18
19
  description: 'Optional source field name (defaults to field_name)'
19
20
  }
20
21
  },
21
- required: [
22
- 'field_name'
23
- ]
22
+ required: []
24
23
  },
25
24
  tags: [
26
25
  'transform',
@@ -15,7 +15,8 @@ export const DataTags = {
15
15
  },
16
16
  default_value: {
17
17
  type: 'string',
18
- description: 'Default value expression for the tags column'
18
+ description: 'Default value expression for the tags column',
19
+ default: 'ARRAY[]::citext[]'
19
20
  },
20
21
  is_required: {
21
22
  type: 'boolean',
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const EventTracker: NodeTypeDefinition;
@@ -0,0 +1,71 @@
1
+ import { conditionDefs, conditionProperties } from '../conditions';
2
+ export const EventTracker = {
3
+ name: 'EventTracker',
4
+ slug: 'event_tracker',
5
+ category: 'event',
6
+ display_name: 'Event Tracker',
7
+ description: 'Creates triggers that record events via the events module when table rows change. ' +
8
+ 'Supports the same compound condition system as JobTrigger (condition_field, watch_fields, ' +
9
+ 'or full AND/OR/NOT conditions). Events are recorded to app_events and aggregated ' +
10
+ 'automatically. Use with achievements (blueprint-level) to unlock levels and grant ' +
11
+ 'credits based on event accumulation.',
12
+ parameter_schema: {
13
+ type: 'object',
14
+ $defs: conditionDefs,
15
+ properties: {
16
+ event_name: {
17
+ type: 'string',
18
+ description: 'Event type name to record (e.g., "avatar_uploaded", "order_completed")'
19
+ },
20
+ events: {
21
+ type: 'array',
22
+ items: {
23
+ type: 'string',
24
+ enum: [
25
+ 'INSERT',
26
+ 'UPDATE',
27
+ 'DELETE'
28
+ ]
29
+ },
30
+ description: 'DML events that trigger recording',
31
+ default: ['INSERT']
32
+ },
33
+ count: {
34
+ type: 'integer',
35
+ description: 'Number of events to record per trigger fire',
36
+ default: 1
37
+ },
38
+ toggle: {
39
+ type: 'boolean',
40
+ description: 'Toggle mode: records event when condition is met, removes when condition is unmet',
41
+ default: false
42
+ },
43
+ actor_field: {
44
+ type: 'string',
45
+ format: 'column-ref',
46
+ description: 'Column containing the actor (user) ID to attribute the event to',
47
+ default: 'owner_id'
48
+ },
49
+ entity_field: {
50
+ type: 'string',
51
+ format: 'column-ref',
52
+ description: 'Column containing the entity ID (org/group) for entity-scoped events. Omit for user-only events.'
53
+ },
54
+ auto_register_type: {
55
+ type: 'boolean',
56
+ description: 'Automatically register the event_name in event_types during provisioning',
57
+ default: true
58
+ },
59
+ ...conditionProperties
60
+ },
61
+ required: [
62
+ 'event_name'
63
+ ]
64
+ },
65
+ tags: [
66
+ 'events',
67
+ 'triggers',
68
+ 'analytics',
69
+ 'tracking'
70
+ ]
71
+ };
@@ -2,15 +2,16 @@ export { CheckGreaterThan } from './check-greater-than';
2
2
  export { CheckLessThan } from './check-less-than';
3
3
  export { CheckNotEqual } from './check-not-equal';
4
4
  export { CheckOneOf } from './check-one-of';
5
- export { LimitAggregate } from './data-aggregate-limit-counter';
6
- export { BillingMeter } from './data-billing-meter';
5
+ export { LimitEnforceAggregate } from './data-aggregate-limit-counter';
6
+ export { LimitTrackUsage } from './data-billing-meter';
7
7
  export { DataBulk } from './data-bulk';
8
8
  export { ProcessChunks } from './data-chunks';
9
9
  export { DataCompositeField } from './data-composite-field';
10
10
  export { DataDirectOwner } from './data-direct-owner';
11
11
  export { DataEntityMembership } from './data-entity-membership';
12
+ export { EventTracker } from './event-tracker';
12
13
  export { ProcessFileEmbedding } from './data-file-embedding';
13
- export { LimitFeatureFlag } from './data-feature-flag';
14
+ export { LimitEnforceFeature } from './data-feature-flag';
14
15
  export { DataForceCurrentUser } from './data-force-current-user';
15
16
  export { DataId } from './data-id';
16
17
  export { ProcessImageEmbedding } from './data-image-embedding';
@@ -18,7 +19,11 @@ export { DataImmutableFields } from './data-immutable-fields';
18
19
  export { DataInflection } from './data-inflection';
19
20
  export { DataInheritFromParent } from './data-inherit-from-parent';
20
21
  export { JobTrigger } from './data-job-trigger';
21
- export { LimitCounter } from './data-limit-counter';
22
+ export { LimitEnforceCounter } from './data-limit-counter';
23
+ export { LimitEnforceRate } from './data-meter-rate-limit';
24
+ export { LimitWarningCounter } from './limit-warning-counter';
25
+ export { LimitWarningAggregate } from './limit-warning-aggregate';
26
+ export { LimitWarningRate } from './limit-warning-rate';
22
27
  export { DataJsonb } from './data-jsonb';
23
28
  export { DataOwnedFields } from './data-owned-fields';
24
29
  export { ProcessExtraction } from './process-extraction';
package/esm/data/index.js CHANGED
@@ -2,15 +2,16 @@ export { CheckGreaterThan } from './check-greater-than';
2
2
  export { CheckLessThan } from './check-less-than';
3
3
  export { CheckNotEqual } from './check-not-equal';
4
4
  export { CheckOneOf } from './check-one-of';
5
- export { LimitAggregate } from './data-aggregate-limit-counter';
6
- export { BillingMeter } from './data-billing-meter';
5
+ export { LimitEnforceAggregate } from './data-aggregate-limit-counter';
6
+ export { LimitTrackUsage } from './data-billing-meter';
7
7
  export { DataBulk } from './data-bulk';
8
8
  export { ProcessChunks } from './data-chunks';
9
9
  export { DataCompositeField } from './data-composite-field';
10
10
  export { DataDirectOwner } from './data-direct-owner';
11
11
  export { DataEntityMembership } from './data-entity-membership';
12
+ export { EventTracker } from './event-tracker';
12
13
  export { ProcessFileEmbedding } from './data-file-embedding';
13
- export { LimitFeatureFlag } from './data-feature-flag';
14
+ export { LimitEnforceFeature } from './data-feature-flag';
14
15
  export { DataForceCurrentUser } from './data-force-current-user';
15
16
  export { DataId } from './data-id';
16
17
  export { ProcessImageEmbedding } from './data-image-embedding';
@@ -18,7 +19,11 @@ export { DataImmutableFields } from './data-immutable-fields';
18
19
  export { DataInflection } from './data-inflection';
19
20
  export { DataInheritFromParent } from './data-inherit-from-parent';
20
21
  export { JobTrigger } from './data-job-trigger';
21
- export { LimitCounter } from './data-limit-counter';
22
+ export { LimitEnforceCounter } from './data-limit-counter';
23
+ export { LimitEnforceRate } from './data-meter-rate-limit';
24
+ export { LimitWarningCounter } from './limit-warning-counter';
25
+ export { LimitWarningAggregate } from './limit-warning-aggregate';
26
+ export { LimitWarningRate } from './limit-warning-rate';
22
27
  export { DataJsonb } from './data-jsonb';
23
28
  export { DataOwnedFields } from './data-owned-fields';
24
29
  export { ProcessExtraction } from './process-extraction';
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const LimitWarningAggregate: NodeTypeDefinition;
@@ -0,0 +1,24 @@
1
+ export const LimitWarningAggregate = {
2
+ name: 'LimitWarningAggregate',
3
+ slug: 'limit_warning_aggregate',
4
+ category: 'limit_warning',
5
+ display_name: 'Warning Aggregate',
6
+ description: 'Attaches an AFTER INSERT trigger that checks if the entity\'s aggregate usage has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor/entity triple. Requires a provisioned limits_module with limit_warnings and aggregate limits enabled.',
7
+ parameter_schema: {
8
+ type: 'object',
9
+ properties: {
10
+ limit_name: {
11
+ type: 'string',
12
+ description: 'Name of the aggregate limit to watch (must match a limit_warnings.name entry, e.g. "databases", "members")',
13
+ },
14
+ entity_field: {
15
+ type: 'string',
16
+ format: 'column-ref',
17
+ description: 'Column on the target table that holds the entity id for aggregate limit lookup',
18
+ default: 'entity_id',
19
+ },
20
+ },
21
+ required: ['limit_name'],
22
+ },
23
+ tags: ['limits', 'triggers', 'aggregates', 'warning', 'notifications'],
24
+ };
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const LimitWarningCounter: NodeTypeDefinition;
@@ -0,0 +1,30 @@
1
+ export const LimitWarningCounter = {
2
+ name: 'LimitWarningCounter',
3
+ slug: 'limit_warning_counter',
4
+ category: 'limit_warning',
5
+ display_name: 'Warning Counter',
6
+ description: 'Attaches an AFTER INSERT trigger that checks if the actor\'s current usage has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor pair. Requires a provisioned limits_module with limit_warnings enabled.',
7
+ parameter_schema: {
8
+ type: 'object',
9
+ properties: {
10
+ limit_name: {
11
+ type: 'string',
12
+ description: 'Name of the limit to watch (must match a limit_warnings.name entry, e.g. "projects", "members")',
13
+ },
14
+ scope: {
15
+ type: 'string',
16
+ enum: ['app', 'org'],
17
+ description: 'Limit scope: "app" (membership_type=1, user-level) or "org" (membership_type=2, entity-level)',
18
+ default: 'app',
19
+ },
20
+ actor_field: {
21
+ type: 'string',
22
+ format: 'column-ref',
23
+ description: 'Column on the target table that holds the actor id for limit lookup',
24
+ default: 'owner_id',
25
+ },
26
+ },
27
+ required: ['limit_name'],
28
+ },
29
+ tags: ['limits', 'triggers', 'warning', 'notifications'],
30
+ };
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const LimitWarningRate: NodeTypeDefinition;
@@ -0,0 +1,30 @@
1
+ export const LimitWarningRate = {
2
+ name: 'LimitWarningRate',
3
+ slug: 'limit_warning_rate',
4
+ category: 'limit_warning',
5
+ display_name: 'Warning Rate Limit',
6
+ description: 'Attaches an AFTER INSERT trigger that checks if the actor\'s current request count in the active sliding window has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor pair. Requires both a limits_module with limit_warnings enabled and a rate_limit_meters_module.',
7
+ parameter_schema: {
8
+ type: 'object',
9
+ properties: {
10
+ meter_slug: {
11
+ type: 'string',
12
+ description: 'Slug of the billing meter to check rate limits against (must match a meters table entry)',
13
+ },
14
+ entity_field: {
15
+ type: 'string',
16
+ format: 'column-ref',
17
+ description: 'Column on the target table that holds the entity id for rate limit lookup',
18
+ default: 'entity_id',
19
+ },
20
+ actor_field: {
21
+ type: 'string',
22
+ format: 'column-ref',
23
+ description: 'Column on the target table that holds the actor id for rate limit lookup',
24
+ default: 'owner_id',
25
+ },
26
+ },
27
+ required: ['meter_slug'],
28
+ },
29
+ tags: ['rate-limits', 'triggers', 'warning', 'notifications', 'metering'],
30
+ };
@@ -1,3 +1,4 @@
1
+ import { conditionDefs, triggerConditionsProperty } from '../conditions';
1
2
  /**
2
3
  * File extraction processing node.
3
4
  *
@@ -22,6 +23,7 @@ export const ProcessExtraction = {
22
23
  'Typically used upstream of ProcessFileEmbedding or ProcessChunks.',
23
24
  parameter_schema: {
24
25
  type: 'object',
26
+ $defs: conditionDefs,
25
27
  properties: {
26
28
  // ── Output fields ─────────────────────────────────────────────
27
29
  text_field: {
@@ -36,6 +38,18 @@ export const ProcessExtraction = {
36
38
  description: 'JSONB field for extraction metadata (page count, language, etc.)',
37
39
  default: 'extracted_metadata'
38
40
  },
41
+ // ── Model config (optional — flows into job payload) ──────────
42
+ extraction_model: {
43
+ type: 'string',
44
+ description: 'Extraction model identifier (e.g. a vision model for OCR, an LLM for ' +
45
+ 'structured extraction). Included in the job payload so the worker knows ' +
46
+ 'which model to use. When null, the worker falls back to runtime config.'
47
+ },
48
+ extraction_provider: {
49
+ type: 'string',
50
+ description: 'Extraction provider name (e.g. "ollama", "openai"). ' +
51
+ 'When null, the worker falls back to runtime config.'
52
+ },
39
53
  // ── MIME scoping ──────────────────────────────────────────────
40
54
  mime_patterns: {
41
55
  type: 'array',
@@ -67,16 +81,7 @@ export const ProcessExtraction = {
67
81
  bucket_id: 'bucket_id'
68
82
  }
69
83
  },
70
- trigger_conditions: {
71
- description: 'Additional compound conditions beyond MIME filtering. ' +
72
- 'Merged with the auto-generated MIME conditions via AND. ' +
73
- 'Use this to add status checks (e.g., status = \'uploaded\').',
74
- 'x-codegen-type': 'TriggerCondition | TriggerCondition[]',
75
- oneOf: [
76
- { $ref: '#/$defs/triggerCondition' },
77
- { type: 'array', items: { $ref: '#/$defs/triggerCondition' } }
78
- ]
79
- },
84
+ trigger_conditions: triggerConditionsProperty,
80
85
  // ── Job options ───────────────────────────────────────────────
81
86
  queue_name: {
82
87
  type: 'string',
@@ -1,3 +1,4 @@
1
+ import { conditionDefs, triggerConditionsProperty } from '../conditions';
1
2
  /**
2
3
  * Image version processing node.
3
4
  *
@@ -23,6 +24,7 @@ export const ProcessImageVersions = {
23
24
  'file records linked to the source image.',
24
25
  parameter_schema: {
25
26
  type: 'object',
27
+ $defs: conditionDefs,
26
28
  required: ['versions'],
27
29
  properties: {
28
30
  // ── Version definitions ───────────────────────────────────────
@@ -98,15 +100,7 @@ export const ProcessImageVersions = {
98
100
  bucket_id: 'bucket_id'
99
101
  }
100
102
  },
101
- trigger_conditions: {
102
- description: 'Additional compound conditions beyond MIME filtering. ' +
103
- 'Merged with the auto-generated MIME conditions via AND.',
104
- 'x-codegen-type': 'TriggerCondition | TriggerCondition[]',
105
- oneOf: [
106
- { $ref: '#/$defs/triggerCondition' },
107
- { type: 'array', items: { $ref: '#/$defs/triggerCondition' } }
108
- ]
109
- },
103
+ trigger_conditions: triggerConditionsProperty,
110
104
  // ── Job options ───────────────────────────────────────────────
111
105
  queue_name: {
112
106
  type: 'string',
@@ -108,6 +108,14 @@ export const SearchUnified = {
108
108
  format: 'column-ref'
109
109
  }
110
110
  },
111
+ embedding_model: {
112
+ type: 'string',
113
+ description: 'Embedding model identifier. When null, the worker falls back to runtime config.'
114
+ },
115
+ embedding_provider: {
116
+ type: 'string',
117
+ description: 'Embedding provider name. When null, the worker falls back to runtime config.'
118
+ },
111
119
  search_score_weight: {
112
120
  type: 'number',
113
121
  default: 1
@@ -161,6 +169,18 @@ export const SearchUnified = {
161
169
  }
162
170
  }
163
171
  },
172
+ embedding_text_field: {
173
+ type: 'string',
174
+ format: 'column-ref',
175
+ description: 'Name of the composite text field created for embedding input',
176
+ default: 'embedding_text'
177
+ },
178
+ composite_format: {
179
+ type: 'string',
180
+ enum: ['labeled', 'plain'],
181
+ description: 'Output format for the composite text field',
182
+ default: 'labeled'
183
+ },
164
184
  trgm_fields: {
165
185
  type: 'array',
166
186
  items: {
@@ -50,6 +50,18 @@ export const SearchVector = {
50
50
  },
51
51
  description: 'Column names that feed the embedding. Used by stale trigger to detect content changes.'
52
52
  },
53
+ // ── Model config (optional — flows into job payload) ──────────
54
+ embedding_model: {
55
+ type: 'string',
56
+ description: 'Embedding model identifier (e.g. "nomic-embed-text", "text-embedding-3-small"). ' +
57
+ 'Included in the job payload so the worker knows which model to use. ' +
58
+ 'When null, the worker falls back to runtime config (llm_module / env vars).'
59
+ },
60
+ embedding_provider: {
61
+ type: 'string',
62
+ description: 'Embedding provider name (e.g. "ollama", "openai"). ' +
63
+ 'When null, the worker falls back to runtime config.'
64
+ },
53
65
  enqueue_job: {
54
66
  type: 'boolean',
55
67
  description: 'Auto-create trigger that enqueues embedding generation jobs',
package/esm/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './authz';
2
2
  export * from './blueprint-types.generated';
3
+ export * from './conditions';
3
4
  export * from './data';
4
5
  export * from './module-presets';
5
6
  export * from './relation';
package/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './authz';
2
2
  export * from './blueprint-types.generated';
3
+ export * from './conditions';
3
4
  export * from './data';
4
5
  export * from './module-presets';
5
6
  export * from './relation';
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './authz';
2
2
  export * from './blueprint-types.generated';
3
+ export * from './conditions';
3
4
  export * from './data';
4
5
  export * from './module-presets';
5
6
  export * from './relation';
package/index.js CHANGED
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.allNodeTypes = void 0;
40
40
  __exportStar(require("./authz"), exports);
41
41
  __exportStar(require("./blueprint-types.generated"), exports);
42
+ __exportStar(require("./conditions"), exports);
42
43
  __exportStar(require("./data"), exports);
43
44
  __exportStar(require("./module-presets"), exports);
44
45
  __exportStar(require("./relation"), exports);