node-type-registry 0.36.0 → 0.38.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 (133) hide show
  1. package/blueprint-types.generated.d.ts +46 -7
  2. package/codegen/generate-types.js +40 -4
  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/index.d.ts +0 -10
  8. package/data/index.js +1 -21
  9. package/data/search-unified.js +8 -0
  10. package/data/search-vector.js +12 -0
  11. package/esm/blueprint-types.generated.d.ts +46 -7
  12. package/esm/codegen/generate-types.js +40 -4
  13. package/esm/conditions/index.d.ts +1 -0
  14. package/esm/conditions/index.js +1 -0
  15. package/esm/conditions/trigger-condition.d.ts +35 -0
  16. package/esm/conditions/trigger-condition.js +94 -0
  17. package/esm/data/index.d.ts +0 -10
  18. package/esm/data/index.js +0 -10
  19. package/esm/data/search-unified.js +8 -0
  20. package/esm/data/search-vector.js +12 -0
  21. package/esm/event/index.d.ts +2 -0
  22. package/esm/event/index.js +2 -0
  23. package/esm/event/referral.d.ts +2 -0
  24. package/esm/event/referral.js +62 -0
  25. package/esm/event/tracker.d.ts +2 -0
  26. package/esm/event/tracker.js +71 -0
  27. package/esm/index.d.ts +5 -0
  28. package/esm/index.js +13 -0
  29. package/esm/job/index.d.ts +1 -0
  30. package/esm/job/index.js +1 -0
  31. package/esm/{data/data-job-trigger.js → job/trigger.js} +3 -53
  32. package/esm/limit/enforce-aggregate.d.ts +2 -0
  33. package/esm/{data/data-aggregate-limit-counter.js → limit/enforce-aggregate.js} +6 -6
  34. package/esm/limit/enforce-counter.d.ts +2 -0
  35. package/esm/{data/data-limit-counter.js → limit/enforce-counter.js} +6 -6
  36. package/esm/limit/enforce-feature.d.ts +2 -0
  37. package/esm/{data/data-feature-flag.js → limit/enforce-feature.js} +6 -6
  38. package/esm/limit/enforce-rate.d.ts +2 -0
  39. package/esm/limit/enforce-rate.js +39 -0
  40. package/esm/limit/index.d.ts +8 -0
  41. package/esm/limit/index.js +8 -0
  42. package/esm/limit/track-usage.d.ts +2 -0
  43. package/esm/{data/data-billing-meter.js → limit/track-usage.js} +6 -6
  44. package/esm/limit/warning-aggregate.d.ts +2 -0
  45. package/esm/limit/warning-aggregate.js +24 -0
  46. package/esm/limit/warning-counter.d.ts +2 -0
  47. package/esm/limit/warning-counter.js +30 -0
  48. package/esm/limit/warning-rate.d.ts +2 -0
  49. package/esm/limit/warning-rate.js +30 -0
  50. package/esm/module-presets/auth-email-magic.js +2 -2
  51. package/esm/module-presets/auth-email.js +5 -5
  52. package/esm/module-presets/auth-hardened.js +2 -2
  53. package/esm/module-presets/auth-passkey.js +2 -2
  54. package/esm/module-presets/auth-sso.d.ts +1 -1
  55. package/esm/module-presets/auth-sso.js +5 -5
  56. package/esm/module-presets/b2b-storage.js +6 -6
  57. package/esm/module-presets/b2b.js +2 -2
  58. package/esm/module-presets/minimal.d.ts +1 -1
  59. package/esm/module-presets/minimal.js +3 -3
  60. package/esm/{data/data-chunks.js → process/chunks.js} +19 -0
  61. package/esm/{data/process-extraction.js → process/extraction.js} +15 -10
  62. package/esm/{data/data-file-embedding.js → process/file-embedding.js} +22 -10
  63. package/esm/{data/data-image-embedding.js → process/image-embedding.js} +15 -9
  64. package/esm/{data/process-image-versions.js → process/image-versions.js} +3 -9
  65. package/esm/process/index.d.ts +5 -0
  66. package/esm/process/index.js +5 -0
  67. package/event/index.d.ts +2 -0
  68. package/event/index.js +7 -0
  69. package/event/referral.d.ts +2 -0
  70. package/event/referral.js +65 -0
  71. package/event/tracker.d.ts +2 -0
  72. package/event/tracker.js +74 -0
  73. package/index.d.ts +5 -0
  74. package/index.js +13 -0
  75. package/job/index.d.ts +1 -0
  76. package/job/index.js +5 -0
  77. package/{data/data-job-trigger.js → job/trigger.js} +3 -53
  78. package/limit/enforce-aggregate.d.ts +2 -0
  79. package/{data/data-aggregate-limit-counter.js → limit/enforce-aggregate.js} +7 -7
  80. package/limit/enforce-counter.d.ts +2 -0
  81. package/{data/data-limit-counter.js → limit/enforce-counter.js} +7 -7
  82. package/limit/enforce-feature.d.ts +2 -0
  83. package/{data/data-feature-flag.js → limit/enforce-feature.js} +7 -7
  84. package/limit/enforce-rate.d.ts +2 -0
  85. package/limit/enforce-rate.js +42 -0
  86. package/limit/index.d.ts +8 -0
  87. package/limit/index.js +19 -0
  88. package/limit/track-usage.d.ts +2 -0
  89. package/{data/data-billing-meter.js → limit/track-usage.js} +7 -7
  90. package/limit/warning-aggregate.d.ts +2 -0
  91. package/limit/warning-aggregate.js +27 -0
  92. package/limit/warning-counter.d.ts +2 -0
  93. package/limit/warning-counter.js +33 -0
  94. package/limit/warning-rate.d.ts +2 -0
  95. package/limit/warning-rate.js +33 -0
  96. package/module-presets/auth-email-magic.js +2 -2
  97. package/module-presets/auth-email.js +5 -5
  98. package/module-presets/auth-hardened.js +2 -2
  99. package/module-presets/auth-passkey.js +2 -2
  100. package/module-presets/auth-sso.d.ts +1 -1
  101. package/module-presets/auth-sso.js +5 -5
  102. package/module-presets/b2b-storage.js +6 -6
  103. package/module-presets/b2b.js +2 -2
  104. package/module-presets/minimal.d.ts +1 -1
  105. package/module-presets/minimal.js +3 -3
  106. package/package.json +2 -2
  107. package/{data/data-chunks.js → process/chunks.js} +19 -0
  108. package/{data/process-extraction.js → process/extraction.js} +15 -10
  109. package/{data/data-file-embedding.js → process/file-embedding.js} +22 -10
  110. package/{data/data-image-embedding.js → process/image-embedding.js} +15 -9
  111. package/{data/process-image-versions.js → process/image-versions.js} +3 -9
  112. package/process/index.d.ts +5 -0
  113. package/process/index.js +13 -0
  114. package/data/data-aggregate-limit-counter.d.ts +0 -2
  115. package/data/data-billing-meter.d.ts +0 -2
  116. package/data/data-feature-flag.d.ts +0 -2
  117. package/data/data-limit-counter.d.ts +0 -2
  118. package/esm/data/data-aggregate-limit-counter.d.ts +0 -2
  119. package/esm/data/data-billing-meter.d.ts +0 -2
  120. package/esm/data/data-feature-flag.d.ts +0 -2
  121. package/esm/data/data-limit-counter.d.ts +0 -2
  122. /package/{data/data-job-trigger.d.ts → esm/job/trigger.d.ts} +0 -0
  123. /package/{data/data-chunks.d.ts → esm/process/chunks.d.ts} +0 -0
  124. /package/{data/process-extraction.d.ts → esm/process/extraction.d.ts} +0 -0
  125. /package/{data/data-file-embedding.d.ts → esm/process/file-embedding.d.ts} +0 -0
  126. /package/{data/data-image-embedding.d.ts → esm/process/image-embedding.d.ts} +0 -0
  127. /package/{data/process-image-versions.d.ts → esm/process/image-versions.d.ts} +0 -0
  128. /package/{esm/data/data-job-trigger.d.ts → job/trigger.d.ts} +0 -0
  129. /package/{esm/data/data-chunks.d.ts → process/chunks.d.ts} +0 -0
  130. /package/{esm/data/process-extraction.d.ts → process/extraction.d.ts} +0 -0
  131. /package/{esm/data/data-file-embedding.d.ts → process/file-embedding.d.ts} +0 -0
  132. /package/{esm/data/data-image-embedding.d.ts → process/image-embedding.d.ts} +0 -0
  133. /package/{esm/data/process-image-versions.d.ts → process/image-versions.d.ts} +0 -0
@@ -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 LimitEnforceFeature: NodeTypeDefinition;
@@ -1,8 +1,8 @@
1
- export const LimitFeatureFlag = {
2
- name: 'LimitFeatureFlag',
3
- slug: 'data_feature_flag',
4
- category: 'limit',
5
- display_name: 'Feature Flag',
1
+ export const LimitEnforceFeature = {
2
+ name: 'LimitEnforceFeature',
3
+ slug: 'limit_enforce_feature',
4
+ category: 'limit_enforce',
5
+ display_name: 'Enforce Feature Flag',
6
6
  description: 'Gates a table behind a feature flag backed by the cap tables. Attaches a BEFORE INSERT trigger that checks whether the named feature cap value is > 0. Features are modeled as caps with max=0 (disabled) or max=1 (enabled) in limit_caps / limit_caps_defaults tables. Resolution: COALESCE(per-entity cap, scope default, 0).',
7
7
  parameter_schema: {
8
8
  type: 'object',
@@ -26,5 +26,5 @@ export const LimitFeatureFlag = {
26
26
  },
27
27
  required: ['feature_name'],
28
28
  },
29
- tags: ['limits', 'triggers', 'feature-flags', 'billing', 'caps'],
29
+ tags: ['limits', 'triggers', 'feature-flags', 'enforce', 'caps'],
30
30
  };
@@ -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
+ };
@@ -0,0 +1,8 @@
1
+ export { LimitEnforceAggregate } from './enforce-aggregate';
2
+ export { LimitEnforceCounter } from './enforce-counter';
3
+ export { LimitEnforceFeature } from './enforce-feature';
4
+ export { LimitEnforceRate } from './enforce-rate';
5
+ export { LimitTrackUsage } from './track-usage';
6
+ export { LimitWarningAggregate } from './warning-aggregate';
7
+ export { LimitWarningCounter } from './warning-counter';
8
+ export { LimitWarningRate } from './warning-rate';
@@ -0,0 +1,8 @@
1
+ export { LimitEnforceAggregate } from './enforce-aggregate';
2
+ export { LimitEnforceCounter } from './enforce-counter';
3
+ export { LimitEnforceFeature } from './enforce-feature';
4
+ export { LimitEnforceRate } from './enforce-rate';
5
+ export { LimitTrackUsage } from './track-usage';
6
+ export { LimitWarningAggregate } from './warning-aggregate';
7
+ export { LimitWarningCounter } from './warning-counter';
8
+ export { LimitWarningRate } from './warning-rate';
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const LimitTrackUsage: NodeTypeDefinition;
@@ -1,8 +1,8 @@
1
- export const BillingMeter = {
2
- name: 'BillingMeter',
3
- slug: 'data_billing_meter',
4
- category: 'billing',
5
- display_name: 'Billing Meter',
1
+ export const LimitTrackUsage = {
2
+ name: 'LimitTrackUsage',
3
+ slug: 'limit_track_usage',
4
+ category: 'limit_track',
5
+ display_name: 'Track Usage',
6
6
  description: 'Declaratively attaches billing usage-recording triggers to a table. On INSERT the named meter is incremented via record_usage; on DELETE it is decremented (reversal). On UPDATE, if the entity_field changes, the old entity is decremented and the new entity is incremented. Requires a provisioned billing_module for the target database.',
7
7
  parameter_schema: {
8
8
  type: 'object',
@@ -34,5 +34,5 @@ export const BillingMeter = {
34
34
  },
35
35
  required: ['meter_slug'],
36
36
  },
37
- tags: ['billing', 'triggers', 'metering', 'usage'],
37
+ tags: ['billing', 'triggers', 'metering', 'usage', 'track'],
38
38
  };
@@ -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
+ };
@@ -38,8 +38,8 @@ export const PresetAuthEmailMagic = {
38
38
  'levels_module:app',
39
39
  'memberships_module:app',
40
40
  'sessions_module',
41
- 'secrets_module',
42
- 'encrypted_secrets_module',
41
+ 'user_state_module',
42
+ 'config_secrets_user_module',
43
43
  'emails_module',
44
44
  'rls_module',
45
45
  'user_auth_module',
@@ -23,7 +23,7 @@ export const PresetAuthEmail = {
23
23
  summary: 'Standard email/password auth flow with app-level permissions. No orgs, no SSO, no MFA.',
24
24
  description: 'Installs `user_auth_module` with exactly the table dependencies its insert trigger ' +
25
25
  'hard-requires: users, app-scoped memberships (plus their permissions/limits/levels ' +
26
- 'dependencies), emails, secrets, encrypted secrets, sessions, plus RLS. You get the ' +
26
+ 'dependencies), emails, user state, user secrets, sessions, plus RLS. You get the ' +
27
27
  'standard password-based auth procedures (sign_up, sign_in, reset_password, ' +
28
28
  "verify_email, delete_account, ...) and that's it. Everything else in the module " +
29
29
  'catalog — SSO, passkeys, SMS, rate limits, orgs, invites — is deliberately omitted. ' +
@@ -49,8 +49,8 @@ export const PresetAuthEmail = {
49
49
  'levels_module:app',
50
50
  'memberships_module:app',
51
51
  'sessions_module',
52
- 'secrets_module',
53
- 'encrypted_secrets_module',
52
+ 'user_state_module',
53
+ 'config_secrets_user_module',
54
54
  'emails_module',
55
55
  'rls_module',
56
56
  'user_auth_module'
@@ -62,8 +62,8 @@ export const PresetAuthEmail = {
62
62
  'limits_module:app': 'Required by `memberships_module:app`: NOT NULL FK to caps table.',
63
63
  'levels_module:app': 'Required by `memberships_module:app`: NOT NULL FK to levels table.',
64
64
  emails_module: 'Required by the `user_auth_module` insert trigger (`RAISE EXCEPTION REQUIRES emails_module`).',
65
- encrypted_secrets_module: 'Required for password hashing; referenced by `set_password`, `verify_password`, and reset flows.',
66
- secrets_module: 'API-key storage (`create_api_key`, `revoke_api_key`, `my_api_keys`).'
65
+ config_secrets_user_module: 'Required for password hashing; referenced by `set_password`, `verify_password`, and reset flows.',
66
+ user_state_module: 'API-key storage (`create_api_key`, `revoke_api_key`, `my_api_keys`).'
67
67
  },
68
68
  omits_notes: {
69
69
  rate_limits_module: 'Omitted intentionally; throttle_* helpers are null-safe and the auth procs compile without it. Add later via `auth:hardened`.',
@@ -35,8 +35,8 @@ export const PresetAuthHardened = {
35
35
  'levels_module:app',
36
36
  'memberships_module:app',
37
37
  'sessions_module',
38
- 'secrets_module',
39
- 'encrypted_secrets_module',
38
+ 'user_state_module',
39
+ 'config_secrets_user_module',
40
40
  'emails_module',
41
41
  'rls_module',
42
42
  'user_auth_module',
@@ -36,8 +36,8 @@ export const PresetAuthPasskey = {
36
36
  'levels_module:app',
37
37
  'memberships_module:app',
38
38
  'sessions_module',
39
- 'secrets_module',
40
- 'encrypted_secrets_module',
39
+ 'user_state_module',
40
+ 'config_secrets_user_module',
41
41
  'emails_module',
42
42
  'rls_module',
43
43
  'user_auth_module',
@@ -6,7 +6,7 @@ import type { ModulePreset } from './types';
6
6
  * `(provider, external_id)`) and `identity_providers_module` (the provider
7
7
  * config: URLs, client_id, encrypted client_secret, scopes, PKCE/nonce
8
8
  * knobs). The generator then emits `sign_in_identity` / `sign_up_identity`
9
- * procedures which rely on `encrypted_secrets_module` to decrypt the client
9
+ * procedures which rely on `config_secrets_user_module` to decrypt the client
10
10
  * secret at auth time.
11
11
  *
12
12
  * Password fallback stays on by default (break-glass for admins); flip the
@@ -5,7 +5,7 @@
5
5
  * `(provider, external_id)`) and `identity_providers_module` (the provider
6
6
  * config: URLs, client_id, encrypted client_secret, scopes, PKCE/nonce
7
7
  * knobs). The generator then emits `sign_in_identity` / `sign_up_identity`
8
- * procedures which rely on `encrypted_secrets_module` to decrypt the client
8
+ * procedures which rely on `config_secrets_user_module` to decrypt the client
9
9
  * secret at auth time.
10
10
  *
11
11
  * Password fallback stays on by default (break-glass for admins); flip the
@@ -26,7 +26,7 @@ export const PresetAuthSso = {
26
26
  'encrypted client secrets) and `connected_accounts_module` (the junction mapping a ' +
27
27
  'Constructive user to a `(provider, external_id)` pair). The generator emits ' +
28
28
  '`sign_in_identity` and `sign_up_identity` procedures which decrypt the client secret ' +
29
- 'through `encrypted_secrets_module` at auth time. Keep password flows as break-glass, or ' +
29
+ 'through `config_secrets_user_module` at auth time. Keep password flows as break-glass, or ' +
30
30
  'disable them via `app_settings_auth` toggles for strictly-SSO deployments.',
31
31
  good_for: [
32
32
  'B2B apps where end users sign in via their employer IdP',
@@ -45,8 +45,8 @@ export const PresetAuthSso = {
45
45
  'levels_module:app',
46
46
  'memberships_module:app',
47
47
  'sessions_module',
48
- 'secrets_module',
49
- 'encrypted_secrets_module',
48
+ 'user_state_module',
49
+ 'config_secrets_user_module',
50
50
  'emails_module',
51
51
  'rls_module',
52
52
  'user_auth_module',
@@ -56,7 +56,7 @@ export const PresetAuthSso = {
56
56
  includes_notes: {
57
57
  connected_accounts_module: 'Junction table for (user, provider, external_id). Without it, `sign_in_identity` does not compile.',
58
58
  identity_providers_module: 'Provider config table (URLs, client_id, encrypted client_secret, scopes, PKCE knobs).',
59
- encrypted_secrets_module: 'Required by `auth:email` already; also used by SSO to decrypt the provider client_secret at auth time.'
59
+ config_secrets_user_module: 'Required by `auth:email` already; also used by SSO to decrypt the provider client_secret at auth time.'
60
60
  },
61
61
  omits_notes: {
62
62
  webauthn_credentials_module: 'No passkeys — add `auth:passkey` or move to `auth:hardened`.',
@@ -17,9 +17,9 @@ export const PresetB2bStorage = {
17
17
  'hierarchy), plus `storage_module` for file uploads. The storage module creates ' +
18
18
  '`app_buckets` and `app_files` tables with full RLS: AuthzPublishable for public reads, ' +
19
19
  'AuthzAppMembership for member access, AuthzDirectOwner for uploader-only modify/delete. ' +
20
- 'Entity-type provisioning with `has_storage=true` adds per-scope storage tables ' +
21
- 'automatically. Choose this when your B2B app needs file uploads, avatars, attachments, ' +
22
- 'or any object storage tied to workspaces.',
20
+ 'Entity-type provisioning with a non-empty `storage` array adds per-scope storage tables ' +
21
+ 'automatically (multiple modules per entity via storage_key). Choose this when your B2B ' +
22
+ 'app needs file uploads, avatars, attachments, or any object storage tied to workspaces.',
23
23
  good_for: [
24
24
  'B2B SaaS with file uploads (documents, avatars, attachments)',
25
25
  'Apps where storage is scoped to orgs/workspaces',
@@ -41,8 +41,8 @@ export const PresetB2bStorage = {
41
41
  'memberships_module:app',
42
42
  'memberships_module:org',
43
43
  'sessions_module',
44
- 'secrets_module',
45
- 'encrypted_secrets_module',
44
+ 'user_state_module',
45
+ 'config_secrets_user_module',
46
46
  'emails_module',
47
47
  'rls_module',
48
48
  'user_auth_module',
@@ -62,7 +62,7 @@ export const PresetB2bStorage = {
62
62
  'devices_module'
63
63
  ],
64
64
  includes_notes: {
65
- storage_module: 'File upload infrastructure: app_buckets + app_files tables with RLS. Entity-type storage scopes layered on top via `has_storage=true`.',
65
+ storage_module: 'File upload infrastructure: app_buckets + app_files tables with RLS. Entity-type storage scopes layered on top via the `storage` array (array-only format, supports multiple modules per entity via storage_key).',
66
66
  devices_module: 'Device tracking and trusted-device MFA bypass.'
67
67
  },
68
68
  omits_notes: {
@@ -37,8 +37,8 @@ export const PresetB2b = {
37
37
  'memberships_module:app',
38
38
  'memberships_module:org',
39
39
  'sessions_module',
40
- 'secrets_module',
41
- 'encrypted_secrets_module',
40
+ 'user_state_module',
41
+ 'config_secrets_user_module',
42
42
  'emails_module',
43
43
  'rls_module',
44
44
  'user_auth_module',
@@ -5,7 +5,7 @@ import type { ModulePreset } from './types';
5
5
  *
6
6
  * This is the barest foundation: a `users` table, a `sessions` table so
7
7
  * something upstream can mint tokens, `rls_module` so row-level security
8
- * is enforceable, and `secrets_module` so you can issue API keys. Nothing
8
+ * is enforceable, and `user_state_module` so you can issue API keys. Nothing
9
9
  * else.
10
10
  *
11
11
  * You still write your own identity bridge on top (or rely on a header-based
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * This is the barest foundation: a `users` table, a `sessions` table so
6
6
  * something upstream can mint tokens, `rls_module` so row-level security
7
- * is enforceable, and `secrets_module` so you can issue API keys. Nothing
7
+ * is enforceable, and `user_state_module` so you can issue API keys. Nothing
8
8
  * else.
9
9
  *
10
10
  * You still write your own identity bridge on top (or rely on a header-based
@@ -32,13 +32,13 @@ export const PresetMinimal = {
32
32
  'users_module',
33
33
  'sessions_module',
34
34
  'rls_module',
35
- 'secrets_module'
35
+ 'user_state_module'
36
36
  ],
37
37
  includes_notes: {
38
38
  users_module: 'The canonical users table. Required by every preset.',
39
39
  sessions_module: 'Session/token storage; needed so whatever upstream auth can mint a session row.',
40
40
  rls_module: 'RLS policy infrastructure. Without it, row-level security is not enforced.',
41
- secrets_module: 'API-key storage. Optional for this preset but almost always wanted alongside upstream auth.'
41
+ user_state_module: 'API-key storage. Optional for this preset but almost always wanted alongside upstream auth.'
42
42
  },
43
43
  omits_notes: {
44
44
  user_auth_module: 'No server-side sign_up/sign_in procedures in this preset.',
@@ -63,6 +63,17 @@ export const ProcessChunks = {
63
63
  description: 'Distance metric for the HNSW index on chunk embeddings',
64
64
  default: 'cosine'
65
65
  },
66
+ // ── Model config (optional — flows into job payload) ──────────
67
+ embedding_model: {
68
+ type: 'string',
69
+ description: 'Embedding model identifier for per-chunk embeddings. ' +
70
+ 'When null, the worker falls back to runtime config (llm_module / env vars).'
71
+ },
72
+ embedding_provider: {
73
+ type: 'string',
74
+ description: 'Embedding provider name (e.g. "ollama", "openai"). ' +
75
+ 'When null, the worker falls back to runtime config.'
76
+ },
66
77
  // ── Table naming ───────────────────────────────────────────────
67
78
  chunks_table_name: {
68
79
  type: 'string',
@@ -74,6 +85,14 @@ export const ProcessChunks = {
74
85
  items: { type: 'string' },
75
86
  description: 'Field names from the parent table to copy into chunk metadata'
76
87
  },
88
+ // ── Search indexes ───────────────────────────────────────────────
89
+ search_indexes: {
90
+ type: 'array',
91
+ items: { type: 'string', enum: ['fulltext', 'bm25', 'trigram'] },
92
+ description: 'Text search indexes to create on the chunks content column. ' +
93
+ 'Omit to mirror the parent table\'s text search indexes. ' +
94
+ 'Set explicitly to override (e.g. ["fulltext", "bm25"]).'
95
+ },
77
96
  // ── Job trigger ────────────────────────────────────────────────
78
97
  enqueue_chunking_job: {
79
98
  type: 'boolean',
@@ -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
  export const ProcessFileEmbedding = {
2
3
  name: 'ProcessFileEmbedding',
3
4
  slug: 'data_file_embedding',
@@ -12,6 +13,7 @@ export const ProcessFileEmbedding = {
12
13
  'names, and embedding strategies.',
13
14
  parameter_schema: {
14
15
  type: 'object',
16
+ $defs: conditionDefs,
15
17
  properties: {
16
18
  // ── Vector config (passed through to SearchVector) ─────────────
17
19
  field_name: {
@@ -42,6 +44,18 @@ export const ProcessFileEmbedding = {
42
44
  description: 'Index-specific options. HNSW: {m, ef_construction}. IVFFlat: {lists}.',
43
45
  default: {}
44
46
  },
47
+ // ── Model config (optional — flows into job payload) ──────────
48
+ embedding_model: {
49
+ type: 'string',
50
+ description: 'Embedding model identifier (e.g. "nomic-embed-text", "text-embedding-3-small", ' +
51
+ '"clip-vit-base-patch32"). Included in the job payload so the worker knows which ' +
52
+ 'model to use. When null, the worker falls back to runtime config (llm_module / env vars).'
53
+ },
54
+ embedding_provider: {
55
+ type: 'string',
56
+ description: 'Embedding provider name (e.g. "ollama", "openai"). ' +
57
+ 'When null, the worker falls back to runtime config.'
58
+ },
45
59
  // ── MIME scoping ───────────────────────────────────────────────
46
60
  mime_patterns: {
47
61
  type: 'array',
@@ -74,16 +88,7 @@ export const ProcessFileEmbedding = {
74
88
  bucket_id: 'bucket_id'
75
89
  }
76
90
  },
77
- trigger_conditions: {
78
- description: 'Additional compound conditions beyond MIME filtering. ' +
79
- 'Merged with the auto-generated MIME conditions via AND. ' +
80
- 'Use this to add status checks, field guards, etc.',
81
- 'x-codegen-type': 'TriggerCondition | TriggerCondition[]',
82
- oneOf: [
83
- { $ref: '#/$defs/triggerCondition' },
84
- { type: 'array', items: { $ref: '#/$defs/triggerCondition' } }
85
- ]
86
- },
91
+ trigger_conditions: triggerConditionsProperty,
87
92
  // ── Extraction config (optional — enables extract mode) ────────
88
93
  extraction: {
89
94
  type: 'object',
@@ -147,6 +152,13 @@ export const ProcessFileEmbedding = {
147
152
  items: { type: 'string' },
148
153
  description: 'Field names from parent to copy into chunk metadata'
149
154
  },
155
+ search_indexes: {
156
+ type: 'array',
157
+ items: { type: 'string', enum: ['fulltext', 'bm25', 'trigram'] },
158
+ description: 'Text search indexes to create on the chunks content column. ' +
159
+ 'Omit to mirror the parent table\'s text search indexes. ' +
160
+ 'Set explicitly to override.'
161
+ },
150
162
  enqueue_chunking_job: {
151
163
  type: 'boolean',
152
164
  description: 'Whether to auto-enqueue a chunking job on insert/update',
@@ -1,3 +1,4 @@
1
+ import { conditionDefs, triggerConditionsProperty } from '../conditions';
1
2
  /**
2
3
  * Image-specific preset of ProcessFileEmbedding.
3
4
  *
@@ -21,6 +22,7 @@ export const ProcessImageEmbedding = {
21
22
  'Accepts all ProcessFileEmbedding parameters — any overrides are forwarded through.',
22
23
  parameter_schema: {
23
24
  type: 'object',
25
+ $defs: conditionDefs,
24
26
  properties: {
25
27
  // ── Vector config (passed through to ProcessFileEmbedding) ──────────
26
28
  field_name: {
@@ -51,6 +53,18 @@ export const ProcessImageEmbedding = {
51
53
  description: 'Index-specific options. HNSW: {m, ef_construction}. IVFFlat: {lists}.',
52
54
  default: {}
53
55
  },
56
+ // ── Model config (optional — flows into job payload) ──────────
57
+ embedding_model: {
58
+ type: 'string',
59
+ description: 'Embedding model identifier (e.g. "clip-vit-base-patch32"). ' +
60
+ 'Included in the job payload so the worker knows which model to use. ' +
61
+ 'When null, the worker falls back to runtime config (llm_module / env vars).'
62
+ },
63
+ embedding_provider: {
64
+ type: 'string',
65
+ description: 'Embedding provider name (e.g. "ollama", "openai"). ' +
66
+ 'When null, the worker falls back to runtime config.'
67
+ },
54
68
  // ── MIME scoping ───────────────────────────────────────────────
55
69
  mime_patterns: {
56
70
  type: 'array',
@@ -81,15 +95,7 @@ export const ProcessImageEmbedding = {
81
95
  bucket_id: 'bucket_id'
82
96
  }
83
97
  },
84
- trigger_conditions: {
85
- description: 'Additional compound conditions beyond MIME filtering. ' +
86
- 'Merged with the auto-generated MIME conditions via AND.',
87
- 'x-codegen-type': 'TriggerCondition | TriggerCondition[]',
88
- oneOf: [
89
- { $ref: '#/$defs/triggerCondition' },
90
- { type: 'array', items: { $ref: '#/$defs/triggerCondition' } }
91
- ]
92
- },
98
+ trigger_conditions: triggerConditionsProperty,
93
99
  // ── Extraction config (optional — enables extract mode) ────────
94
100
  extraction: {
95
101
  type: 'object',