node-type-registry 0.42.0 → 0.43.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 (57) hide show
  1. package/authz/authz-app-membership.js +8 -8
  2. package/authz/index.d.ts +2 -2
  3. package/authz/index.js +5 -5
  4. package/blueprint-types.generated.d.ts +99 -10
  5. package/codegen/generate-types.js +56 -2
  6. package/data/check-greater-than.js +6 -6
  7. package/data/check-less-than.js +6 -6
  8. package/data/check-not-equal.js +4 -4
  9. package/data/check-one-of.js +5 -5
  10. package/data/data-jsonb.js +4 -3
  11. package/data/data-status-field.js +4 -3
  12. package/data/data-tags.js +4 -3
  13. package/esm/authz/authz-app-membership.js +8 -8
  14. package/esm/authz/index.d.ts +2 -2
  15. package/esm/authz/index.js +2 -2
  16. package/esm/blueprint-types.generated.d.ts +99 -10
  17. package/esm/codegen/generate-types.js +56 -2
  18. package/esm/data/check-greater-than.js +6 -6
  19. package/esm/data/check-less-than.js +6 -6
  20. package/esm/data/check-not-equal.js +4 -4
  21. package/esm/data/check-one-of.js +5 -5
  22. package/esm/data/data-jsonb.js +4 -3
  23. package/esm/data/data-status-field.js +4 -3
  24. package/esm/data/data-tags.js +4 -3
  25. package/esm/event/referral.js +21 -2
  26. package/esm/event/tracker.js +20 -1
  27. package/esm/index.d.ts +1 -1
  28. package/esm/limit/enforce-aggregate.js +32 -8
  29. package/esm/limit/enforce-counter.js +33 -10
  30. package/esm/limit/enforce-feature.js +26 -8
  31. package/esm/limit/enforce-rate.js +28 -9
  32. package/esm/limit/track-usage.js +28 -9
  33. package/esm/limit/warning-aggregate.js +29 -5
  34. package/esm/limit/warning-counter.js +30 -7
  35. package/esm/limit/warning-rate.js +31 -7
  36. package/esm/module-presets/full.js +1 -1
  37. package/esm/process/chunks.js +1 -1
  38. package/esm/process/file-embedding.js +1 -1
  39. package/esm/types.d.ts +92 -0
  40. package/esm/types.js +1 -0
  41. package/event/referral.js +21 -2
  42. package/event/tracker.js +20 -1
  43. package/index.d.ts +1 -1
  44. package/limit/enforce-aggregate.js +32 -8
  45. package/limit/enforce-counter.js +33 -10
  46. package/limit/enforce-feature.js +26 -8
  47. package/limit/enforce-rate.js +28 -9
  48. package/limit/track-usage.js +28 -9
  49. package/limit/warning-aggregate.js +29 -5
  50. package/limit/warning-counter.js +30 -7
  51. package/limit/warning-rate.js +31 -7
  52. package/module-presets/full.js +1 -1
  53. package/package.json +2 -2
  54. package/process/chunks.js +1 -1
  55. package/process/file-embedding.js +1 -1
  56. package/types.d.ts +92 -0
  57. package/types.js +1 -0
@@ -12,31 +12,54 @@ exports.LimitEnforceCounter = {
12
12
  properties: {
13
13
  limit_name: {
14
14
  type: 'string',
15
- description: 'Name of the limit to track (must match a default_limits entry, e.g. "projects", "members")',
15
+ description: 'Name of the limit to track (must match a default_limits entry, e.g. "projects", "members")'
16
16
  },
17
17
  scope: {
18
18
  type: 'string',
19
- enum: ['app', 'org'],
20
- description: 'Limit scope: "app" (membership_type=1, user-level) or "org" (membership_type=2, entity-level)',
21
- default: 'app',
19
+ description: 'Membership type prefix that determines which limits_module row to use. Resolved dynamically via memberships_module — supports any provisioned type (e.g. "app", "org", "data_room", "channel", "team").',
20
+ default: 'app'
22
21
  },
23
22
  actor_field: {
24
23
  type: 'string',
25
24
  format: 'column-ref',
26
25
  description: 'Column on the target table that holds the actor or entity id used for limit lookup',
27
- default: 'owner_id',
26
+ default: 'owner_id'
27
+ },
28
+ entity_field: {
29
+ type: 'string',
30
+ format: 'column-ref',
31
+ description: 'Column on the target table that holds (or references) the entity id for entity context resolution. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.'
32
+ },
33
+ entity_lookup: {
34
+ type: 'object',
35
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
36
+ properties: {
37
+ obj_table: {
38
+ type: 'string',
39
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
40
+ },
41
+ obj_schema: {
42
+ type: 'string',
43
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
44
+ },
45
+ obj_field: {
46
+ type: 'string',
47
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
48
+ }
49
+ },
50
+ required: ['obj_table', 'obj_field']
28
51
  },
29
52
  events: {
30
53
  type: 'array',
31
54
  items: {
32
55
  type: 'string',
33
- enum: ['INSERT', 'DELETE', 'UPDATE'],
56
+ enum: ['INSERT', 'DELETE', 'UPDATE']
34
57
  },
35
58
  description: 'Which DML events to attach triggers for',
36
- default: ['INSERT', 'DELETE'],
37
- },
59
+ default: ['INSERT', 'DELETE']
60
+ }
38
61
  },
39
- required: ['limit_name'],
62
+ required: ['limit_name']
40
63
  },
41
- tags: ['limits', 'triggers', 'enforce'],
64
+ tags: ['limits', 'triggers', 'enforce']
42
65
  };
@@ -12,22 +12,40 @@ exports.LimitEnforceFeature = {
12
12
  properties: {
13
13
  feature_name: {
14
14
  type: 'string',
15
- description: 'Cap name representing this feature (must match a limit_caps_defaults entry with max=0 or max=1)',
15
+ description: 'Cap name representing this feature (must match a limit_caps_defaults entry with max=0 or max=1)'
16
16
  },
17
17
  scope: {
18
18
  type: 'string',
19
- enum: ['app', 'org'],
20
- description: 'Feature scope: "app" (membership_type=1, app-level caps) or "org" (membership_type=2, per-entity caps)',
21
- default: 'app',
19
+ description: 'Membership type prefix that determines which limits_module row to use. Resolved dynamically via memberships_module — supports any provisioned type (e.g. "app", "org", "data_room", "channel", "team").',
20
+ default: 'app'
22
21
  },
23
22
  entity_field: {
24
23
  type: 'string',
25
24
  format: 'column-ref',
26
- description: 'Column on the target table that holds the entity id for per-entity cap lookups (only used for org scope)',
27
- default: 'entity_id',
25
+ description: 'Column on the target table that holds (or references) the entity id for per-entity cap lookups (only used for org scope). For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.',
26
+ default: 'entity_id'
28
27
  },
28
+ entity_lookup: {
29
+ type: 'object',
30
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
31
+ properties: {
32
+ obj_table: {
33
+ type: 'string',
34
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
35
+ },
36
+ obj_schema: {
37
+ type: 'string',
38
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
39
+ },
40
+ obj_field: {
41
+ type: 'string',
42
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
43
+ }
44
+ },
45
+ required: ['obj_table', 'obj_field']
46
+ }
29
47
  },
30
- required: ['feature_name'],
48
+ required: ['feature_name']
31
49
  },
32
- tags: ['limits', 'triggers', 'feature-flags', 'enforce', 'caps'],
50
+ tags: ['limits', 'triggers', 'feature-flags', 'enforce', 'caps']
33
51
  };
@@ -12,31 +12,50 @@ exports.LimitEnforceRate = {
12
12
  properties: {
13
13
  meter_slug: {
14
14
  type: 'string',
15
- description: 'Slug of the billing meter to check rate limits against (must match a meters table entry, e.g. "messaging", "inference")',
15
+ description: 'Slug of the billing meter to check rate limits against (must match a meters table entry, e.g. "messaging", "inference")'
16
16
  },
17
17
  entity_field: {
18
18
  type: 'string',
19
19
  format: 'column-ref',
20
- description: 'Column on the target table that holds the entity id (org) for rate limiting',
21
- default: 'entity_id',
20
+ description: 'Column on the target table that holds (or references) the entity id for rate limiting. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.',
21
+ default: 'entity_id'
22
+ },
23
+ entity_lookup: {
24
+ type: 'object',
25
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
26
+ properties: {
27
+ obj_table: {
28
+ type: 'string',
29
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
30
+ },
31
+ obj_schema: {
32
+ type: 'string',
33
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
34
+ },
35
+ obj_field: {
36
+ type: 'string',
37
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
38
+ }
39
+ },
40
+ required: ['obj_table', 'obj_field']
22
41
  },
23
42
  actor_field: {
24
43
  type: 'string',
25
44
  format: 'column-ref',
26
45
  description: 'Column on the target table that holds the actor id (user) for rate limiting',
27
- default: 'owner_id',
46
+ default: 'owner_id'
28
47
  },
29
48
  events: {
30
49
  type: 'array',
31
50
  items: {
32
51
  type: 'string',
33
- enum: ['INSERT', 'UPDATE'],
52
+ enum: ['INSERT', 'UPDATE']
34
53
  },
35
54
  description: 'Which DML events to enforce rate limits on (DELETE is excluded since it reduces load)',
36
- default: ['INSERT'],
37
- },
55
+ default: ['INSERT']
56
+ }
38
57
  },
39
- required: ['meter_slug'],
58
+ required: ['meter_slug']
40
59
  },
41
- tags: ['rate-limits', 'triggers', 'enforce', 'metering', 'abuse-protection'],
60
+ tags: ['rate-limits', 'triggers', 'enforce', 'metering', 'abuse-protection']
42
61
  };
@@ -12,30 +12,49 @@ exports.LimitTrackUsage = {
12
12
  properties: {
13
13
  meter_slug: {
14
14
  type: 'string',
15
- description: 'Slug of the billing meter to record usage against (must match a meters table entry, e.g. "databases", "seats")',
15
+ description: 'Slug of the billing meter to record usage against (must match a meters table entry, e.g. "databases", "seats")'
16
16
  },
17
17
  entity_field: {
18
18
  type: 'string',
19
19
  format: 'column-ref',
20
- description: 'Column on the target table that holds the entity id for billing',
21
- default: 'entity_id',
20
+ description: 'Column on the target table that holds (or references) the entity id for billing. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.',
21
+ default: 'entity_id'
22
+ },
23
+ entity_lookup: {
24
+ type: 'object',
25
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
26
+ properties: {
27
+ obj_table: {
28
+ type: 'string',
29
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
30
+ },
31
+ obj_schema: {
32
+ type: 'string',
33
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
34
+ },
35
+ obj_field: {
36
+ type: 'string',
37
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
38
+ }
39
+ },
40
+ required: ['obj_table', 'obj_field']
22
41
  },
23
42
  quantity: {
24
43
  type: 'integer',
25
44
  description: 'Units to record per event (default 1)',
26
- default: 1,
45
+ default: 1
27
46
  },
28
47
  events: {
29
48
  type: 'array',
30
49
  items: {
31
50
  type: 'string',
32
- enum: ['INSERT', 'DELETE', 'UPDATE'],
51
+ enum: ['INSERT', 'DELETE', 'UPDATE']
33
52
  },
34
53
  description: 'Which DML events to attach triggers for',
35
- default: ['INSERT', 'DELETE'],
36
- },
54
+ default: ['INSERT', 'DELETE']
55
+ }
37
56
  },
38
- required: ['meter_slug'],
57
+ required: ['meter_slug']
39
58
  },
40
- tags: ['billing', 'triggers', 'metering', 'usage', 'track'],
59
+ tags: ['billing', 'triggers', 'metering', 'usage', 'track']
41
60
  };
@@ -12,16 +12,40 @@ exports.LimitWarningAggregate = {
12
12
  properties: {
13
13
  limit_name: {
14
14
  type: 'string',
15
- description: 'Name of the aggregate limit to watch (must match a limit_warnings.name entry, e.g. "databases", "members")',
15
+ description: 'Name of the aggregate limit to watch (must match a limit_warnings.name entry, e.g. "databases", "members")'
16
+ },
17
+ scope: {
18
+ type: 'string',
19
+ description: 'Membership type prefix that determines which limits_module row to use. Resolved dynamically via memberships_module — supports any provisioned type (e.g. "org", "data_room", "channel", "team").',
20
+ default: 'org'
16
21
  },
17
22
  entity_field: {
18
23
  type: 'string',
19
24
  format: 'column-ref',
20
- description: 'Column on the target table that holds the entity id for aggregate limit lookup',
21
- default: 'entity_id',
25
+ description: 'Column on the target table that holds (or references) the entity id for aggregate limit lookup. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.',
26
+ default: 'entity_id'
22
27
  },
28
+ entity_lookup: {
29
+ type: 'object',
30
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
31
+ properties: {
32
+ obj_table: {
33
+ type: 'string',
34
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
35
+ },
36
+ obj_schema: {
37
+ type: 'string',
38
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
39
+ },
40
+ obj_field: {
41
+ type: 'string',
42
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
43
+ }
44
+ },
45
+ required: ['obj_table', 'obj_field']
46
+ }
23
47
  },
24
- required: ['limit_name'],
48
+ required: ['limit_name']
25
49
  },
26
- tags: ['limits', 'triggers', 'aggregates', 'warning', 'notifications'],
50
+ tags: ['limits', 'triggers', 'aggregates', 'warning', 'notifications']
27
51
  };
@@ -12,22 +12,45 @@ exports.LimitWarningCounter = {
12
12
  properties: {
13
13
  limit_name: {
14
14
  type: 'string',
15
- description: 'Name of the limit to watch (must match a limit_warnings.name entry, e.g. "projects", "members")',
15
+ description: 'Name of the limit to watch (must match a limit_warnings.name entry, e.g. "projects", "members")'
16
16
  },
17
17
  scope: {
18
18
  type: 'string',
19
- enum: ['app', 'org'],
20
- description: 'Limit scope: "app" (membership_type=1, user-level) or "org" (membership_type=2, entity-level)',
21
- default: 'app',
19
+ description: 'Membership type prefix that determines which limits_module row to use. Resolved dynamically via memberships_module — supports any provisioned type (e.g. "app", "org", "data_room", "channel", "team").',
20
+ default: 'app'
22
21
  },
23
22
  actor_field: {
24
23
  type: 'string',
25
24
  format: 'column-ref',
26
25
  description: 'Column on the target table that holds the actor id for limit lookup',
27
- default: 'owner_id',
26
+ default: 'owner_id'
28
27
  },
28
+ entity_field: {
29
+ type: 'string',
30
+ format: 'column-ref',
31
+ description: 'Column on the target table that holds (or references) the entity id. When provided, entity_id is included in the job payload and dedup state. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.'
32
+ },
33
+ entity_lookup: {
34
+ type: 'object',
35
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
36
+ properties: {
37
+ obj_table: {
38
+ type: 'string',
39
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
40
+ },
41
+ obj_schema: {
42
+ type: 'string',
43
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
44
+ },
45
+ obj_field: {
46
+ type: 'string',
47
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
48
+ }
49
+ },
50
+ required: ['obj_table', 'obj_field']
51
+ }
29
52
  },
30
- required: ['limit_name'],
53
+ required: ['limit_name']
31
54
  },
32
- tags: ['limits', 'triggers', 'warning', 'notifications'],
55
+ tags: ['limits', 'triggers', 'warning', 'notifications']
33
56
  };
@@ -12,22 +12,46 @@ exports.LimitWarningRate = {
12
12
  properties: {
13
13
  meter_slug: {
14
14
  type: 'string',
15
- description: 'Slug of the billing meter to check rate limits against (must match a meters table entry)',
15
+ description: 'Slug of the billing meter to check rate limits against (must match a meters table entry)'
16
+ },
17
+ scope: {
18
+ type: 'string',
19
+ description: 'Membership type prefix that determines which limits_module row to use for warnings and warning_state tables. Resolved dynamically via memberships_module — supports any provisioned type (e.g. "app", "org", "data_room", "channel", "team").',
20
+ default: 'app'
16
21
  },
17
22
  entity_field: {
18
23
  type: 'string',
19
24
  format: 'column-ref',
20
- description: 'Column on the target table that holds the entity id for rate limit lookup',
21
- default: 'entity_id',
25
+ description: 'Column on the target table that holds (or references) the entity id for rate limit lookup. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.',
26
+ default: 'entity_id'
27
+ },
28
+ entity_lookup: {
29
+ type: 'object',
30
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
31
+ properties: {
32
+ obj_table: {
33
+ type: 'string',
34
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
35
+ },
36
+ obj_schema: {
37
+ type: 'string',
38
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
39
+ },
40
+ obj_field: {
41
+ type: 'string',
42
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
43
+ }
44
+ },
45
+ required: ['obj_table', 'obj_field']
22
46
  },
23
47
  actor_field: {
24
48
  type: 'string',
25
49
  format: 'column-ref',
26
50
  description: 'Column on the target table that holds the actor id for rate limit lookup',
27
- default: 'owner_id',
28
- },
51
+ default: 'owner_id'
52
+ }
29
53
  },
30
- required: ['meter_slug'],
54
+ required: ['meter_slug']
31
55
  },
32
- tags: ['rate-limits', 'triggers', 'warning', 'notifications', 'metering'],
56
+ tags: ['rate-limits', 'triggers', 'warning', 'notifications', 'metering']
33
57
  };
@@ -79,7 +79,7 @@ exports.PresetFull = {
79
79
  'user_auth_module',
80
80
  'webauthn_auth_module',
81
81
  // Storage (full features)
82
- 'storage_module:full',
82
+ 'storage_module:full'
83
83
  ],
84
84
  includes_notes: {
85
85
  'storage_module:full': 'All storage feature flags enabled: versioning, content hash, custom keys, audit log.',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-type-registry",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "description": "Node type definitions for the Constructive blueprint system. Single source of truth for all Authz*, Data*, Relation*, and View* node types.",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "main": "index.js",
@@ -47,5 +47,5 @@
47
47
  "registry",
48
48
  "graphile"
49
49
  ],
50
- "gitHead": "72ffa0944cbf0386b9f2f5dfd6640879bb30e38d"
50
+ "gitHead": "c9317afa5b5c2401ab1a18c927c3fd75b59a0b01"
51
51
  }
package/process/chunks.js CHANGED
@@ -80,7 +80,7 @@ exports.ProcessChunks = {
80
80
  // ── Table naming ───────────────────────────────────────────────
81
81
  chunks_table_name: {
82
82
  type: 'string',
83
- description: 'Override the chunks table name. Defaults to {parent_table}_chunks.',
83
+ description: 'Override the chunks table name. Defaults to {parent_table}_chunks.'
84
84
  },
85
85
  // ── Metadata ───────────────────────────────────────────────────
86
86
  metadata_fields: {
@@ -135,7 +135,7 @@ exports.ProcessFileEmbedding = {
135
135
  type: 'boolean',
136
136
  description: 'Whether to create a chunks table via ProcessChunks. Defaults to true ' +
137
137
  'when extraction is provided, false in direct mode. Set explicitly ' +
138
- 'to override.',
138
+ 'to override.'
139
139
  },
140
140
  chunks: {
141
141
  type: 'object',
package/types.d.ts CHANGED
@@ -1,3 +1,95 @@
1
+ /**
2
+ * Structured representation of a PostgreSQL data type.
3
+ *
4
+ * Stored as JSONB in `metaschema_public.field.type`.
5
+ *
6
+ * @example Simple type
7
+ * { name: "text" }
8
+ *
9
+ * @example Type with arguments
10
+ * { name: "geometry", args: ["Point", 4326] }
11
+ * { name: "numeric", args: [10, 2] }
12
+ * { name: "vector", args: [1536] }
13
+ *
14
+ * @example Array type
15
+ * { name: "text", array_dimensions: 1 }
16
+ *
17
+ * @example Schema-qualified type
18
+ * { name: "my_type", schema: "my_schema" }
19
+ *
20
+ * @example Interval with field range
21
+ * { name: "interval", range: ["day", "second"] }
22
+ */
23
+ export interface FieldType {
24
+ /** Type name (required). Must be a valid SQL identifier. */
25
+ name: string;
26
+ /** Schema qualifier (optional). Must be a valid SQL identifier. */
27
+ schema?: string;
28
+ /** Type arguments (optional). Each is a string identifier, number, or boolean. */
29
+ args?: (string | number | boolean)[];
30
+ /** Number of array dimensions (optional). 1 = `text[]`, 2 = `text[][]`. */
31
+ array_dimensions?: number;
32
+ /** Interval field range (optional). 1-2 elements: ["day"] or ["day", "second"]. */
33
+ range?: string[];
34
+ }
35
+ /**
36
+ * Argument to a function in a FieldDefault expression.
37
+ * Can be a literal value or a nested FieldDefault (recursive).
38
+ */
39
+ export type FieldDefaultArg = string | number | boolean | null | FieldDefault;
40
+ /**
41
+ * Structured representation of a PostgreSQL default value expression.
42
+ *
43
+ * Stored as JSONB in `metaschema_public.field.default_value`.
44
+ *
45
+ * @example Literal values
46
+ * { value: false }
47
+ * { value: 0 }
48
+ * { value: "pooled" }
49
+ *
50
+ * @example Cast expression
51
+ * { value: {}, cast: { name: "jsonb" } }
52
+ * { value: "15 minutes", cast: { name: "interval" } }
53
+ *
54
+ * @example Simple function call
55
+ * { function: "now" }
56
+ * { function: "gen_random_uuid" }
57
+ *
58
+ * @example Schema-qualified function
59
+ * { function: "current_user_id", schema: "jwt_public" }
60
+ *
61
+ * @example Function with arguments (nested)
62
+ * { function: "encode", args: [{ function: "gen_random_bytes", args: [{ value: 16 }] }, { value: "hex" }] }
63
+ *
64
+ * @example Function with cast
65
+ * { function: "lpad", args: [{ value: "" }, { value: 32 }, { value: "0" }], cast: { name: "bit", args: [32] } }
66
+ *
67
+ * @example Operator expression
68
+ * { operator: "+", left: { function: "now" }, right: { value: "5 minutes", cast: { name: "interval" } } }
69
+ *
70
+ * @example SQL keyword
71
+ * { sql_keyword: "CURRENT_TIMESTAMP" }
72
+ */
73
+ export interface FieldDefault {
74
+ /** Literal value (string, number, boolean, null, array, or object). */
75
+ value?: string | number | boolean | null | unknown[] | Record<string, unknown>;
76
+ /** Function name. Must be a valid SQL identifier. */
77
+ function?: string;
78
+ /** Schema qualifier for function (optional). */
79
+ schema?: string;
80
+ /** Function arguments (optional, recursive). */
81
+ args?: FieldDefaultArg[];
82
+ /** Output type cast (optional). Reuses FieldType shape. */
83
+ cast?: FieldType;
84
+ /** Binary operator (e.g., "+", "-", "||"). */
85
+ operator?: string;
86
+ /** Left operand for operator expression. */
87
+ left?: FieldDefault;
88
+ /** Right operand for operator expression. */
89
+ right?: FieldDefault;
90
+ /** SQL keyword (e.g., "CURRENT_TIMESTAMP", "CURRENT_USER"). */
91
+ sql_keyword?: string;
92
+ }
1
93
  /**
2
94
  * JSON Schema type definition.
3
95
  *
package/types.js CHANGED
@@ -1,2 +1,3 @@
1
1
  "use strict";
2
+ // ─── FieldType / FieldDefault ─────────────────────────────────────
2
3
  Object.defineProperty(exports, "__esModule", { value: true });