@cosmicdrift/kumiko-bundled-features 0.352.0 → 0.353.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 (105) hide show
  1. package/dist/agent-tools/agent-manifest.js +8 -2
  2. package/dist/agent-tools/manifest-deny-qns.d.ts +3 -0
  3. package/dist/agent-tools/manifest-deny-qns.js +17 -0
  4. package/dist/agent-tools/tool-catalog.d.ts +2 -1
  5. package/dist/agent-tools/tool-catalog.js +4 -1
  6. package/dist/audit/handlers/list.query.js +13 -8
  7. package/dist/auth-email-password/handlers/signup-confirm.write.js +2 -3
  8. package/dist/auth-mfa/schema/user-mfa.d.ts +6 -0
  9. package/dist/auth-mfa/screens.js +2 -2
  10. package/dist/billing-foundation/checkout-core.d.ts +7 -0
  11. package/dist/billing-foundation/checkout-core.js +7 -2
  12. package/dist/billing-foundation/entities.d.ts +8 -0
  13. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +7 -1
  14. package/dist/billing-foundation/projection.d.ts +8 -0
  15. package/dist/cap-counter/entity.d.ts +1 -0
  16. package/dist/cap-overview/access.js +2 -9
  17. package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -2
  18. package/dist/cap-overview/handlers/tenant-options.query.js +4 -5
  19. package/dist/compliance-profiles/schema/profile-selection.d.ts +8 -8
  20. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +2 -4
  21. package/dist/config/handlers/values.query.d.ts +3 -1
  22. package/dist/config/handlers/values.query.js +7 -2
  23. package/dist/config/table.d.ts +6 -0
  24. package/dist/custom-fields/entity.d.ts +4 -0
  25. package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -0
  26. package/dist/delivery/public-names.js +1 -1
  27. package/dist/delivery/tables.d.ts +6 -0
  28. package/dist/document-ingest-foundation/entity.d.ts +4 -0
  29. package/dist/files-tenant-data/hooks.js +3 -2
  30. package/dist/folders/entity.d.ts +8 -0
  31. package/dist/folders/feature.js +2 -10
  32. package/dist/form-draft/db/queries/cleanup.d.ts +1 -1
  33. package/dist/form-draft/db/queries/cleanup.js +4 -3
  34. package/dist/form-draft/entity.d.ts +2 -0
  35. package/dist/form-draft/handlers/cleanup.job.d.ts +5 -1
  36. package/dist/form-draft/handlers/cleanup.job.js +11 -5
  37. package/dist/inbound-mail-foundation/entities.d.ts +25 -0
  38. package/dist/inbound-mail-foundation/projection.d.ts +20 -0
  39. package/dist/jobs/handlers/list.query.d.ts +2 -1
  40. package/dist/jobs/handlers/list.query.js +39 -14
  41. package/dist/jobs/i18n.js +1 -0
  42. package/dist/jobs/job-run-table.d.ts +6 -0
  43. package/dist/ledger/entity.d.ts +21 -8
  44. package/dist/ledger/entity.js +4 -0
  45. package/dist/ledger/schemas.js +8 -2
  46. package/dist/managed-pages/feature.js +28 -10
  47. package/dist/managed-pages/table.d.ts +12 -0
  48. package/dist/notes-history/entity.d.ts +12 -0
  49. package/dist/notes-history/feature.js +2 -10
  50. package/dist/personal-access-tokens/schema/api-token.d.ts +6 -0
  51. package/dist/personal-access-tokens/screens.js +14 -3
  52. package/dist/secrets/table.d.ts +1 -0
  53. package/dist/seo/feature.js +28 -6
  54. package/dist/sessions/schema/user-session.d.ts +4 -0
  55. package/dist/shared/assert-no-where-rule-in-ownership-write.d.ts +2 -0
  56. package/dist/shared/assert-no-where-rule-in-ownership-write.js +18 -0
  57. package/dist/shared/index.d.ts +2 -1
  58. package/dist/shared/index.js +2 -1
  59. package/dist/shared/rate-limited-text-response.d.ts +2 -0
  60. package/dist/shared/rate-limited-text-response.js +9 -0
  61. package/dist/tags/entity.d.ts +9 -0
  62. package/dist/tags/feature.js +2 -10
  63. package/dist/template-resolver/table.d.ts +40 -30
  64. package/dist/template-resolver/user-content-table.d.ts +30 -20
  65. package/dist/tenant/decrypt-tenant-names.d.ts +3 -0
  66. package/dist/tenant/decrypt-tenant-names.js +10 -0
  67. package/dist/tenant/handlers/me.query.js +5 -1
  68. package/dist/tenant/handlers/memberships.query.js +3 -2
  69. package/dist/tenant/handlers/tenant-directory.query.js +9 -3
  70. package/dist/tenant/index.d.ts +1 -0
  71. package/dist/tenant/index.js +1 -0
  72. package/dist/tenant/invitation-table.d.ts +14 -8
  73. package/dist/tenant/membership-table.d.ts +4 -0
  74. package/dist/tenant/schema/tenant.d.ts +16 -10
  75. package/dist/tenant/schema/tenant.js +4 -6
  76. package/dist/tenant/screens.js +1 -1
  77. package/dist/tenant-handover/move-entity-graph.js +11 -18
  78. package/dist/tenant-lifecycle/feature.js +1 -0
  79. package/dist/tenant-lifecycle/run-tenant-destroy.d.ts +3 -0
  80. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -0
  81. package/dist/tenant-lifecycle/stages.d.ts +2 -0
  82. package/dist/tenant-lifecycle/stages.js +7 -1
  83. package/dist/tier-engine/entity.d.ts +2 -0
  84. package/dist/tier-engine/tier-resolver.d.ts +2 -0
  85. package/dist/user/handlers/list.query.js +2 -2
  86. package/dist/user/schema/user.d.ts +20 -8
  87. package/dist/user-data-rights/boot-checks.js +5 -0
  88. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +2 -2
  89. package/dist/user-data-rights/schema/download-attempt.d.ts +14 -0
  90. package/dist/user-data-rights/schema/download-token.d.ts +8 -0
  91. package/dist/user-data-rights/schema/export-job.d.ts +14 -8
  92. package/dist/waitlist/entity.d.ts +20 -6
  93. package/dist/workflow-runner/event-trigger.js +6 -3
  94. package/dist/workflow-runner/handlers/resume-run.write.js +3 -0
  95. package/package.json +9 -9
  96. package/src/agent-tools/changes.json +12 -0
  97. package/src/audit/changes.json +6 -0
  98. package/src/form-draft/changes.json +7 -1
  99. package/src/managed-pages/changes.json +6 -0
  100. package/src/seo/changes.json +5 -0
  101. package/src/tenant/changes.json +7 -0
  102. package/src/tenant-handover/changes.json +6 -0
  103. package/src/workflow-runner/changes.json +5 -0
  104. package/dist/shared/has-where-rule.d.ts +0 -2
  105. package/dist/shared/has-where-rule.js +0 -10
@@ -4,6 +4,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
4
4
  readonly type: "text";
5
5
  readonly description?: string;
6
6
  readonly maxLength?: number;
7
+ readonly minLength?: number;
7
8
  readonly required?: boolean;
8
9
  readonly searchable?: boolean;
9
10
  readonly sortable?: boolean;
@@ -33,12 +34,12 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
33
34
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
34
35
  readonly display?: "radio" | "dropdown";
35
36
  readonly optionTones?: {
36
- readonly "ai-prompt"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
37
- readonly "document-pdf"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
38
- readonly "image-snapshot"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
39
- readonly "mail-html"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
40
- readonly notification?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
41
- readonly "text-block"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
37
+ readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
38
+ readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
39
+ readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
40
+ readonly "mail-html"?: "bad" | "neutral" | "ok" | "warn" | undefined;
41
+ readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
42
+ readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
42
43
  } | undefined;
43
44
  readonly optionsQuery?: string;
44
45
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -50,6 +51,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
50
51
  readonly type: "text";
51
52
  readonly description?: string;
52
53
  readonly maxLength?: number;
54
+ readonly minLength?: number;
53
55
  readonly required?: boolean;
54
56
  readonly searchable?: boolean;
55
57
  readonly sortable?: boolean;
@@ -71,6 +73,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
71
73
  readonly type: "text";
72
74
  readonly description?: string;
73
75
  readonly maxLength?: number;
76
+ readonly minLength?: number;
74
77
  readonly required?: boolean;
75
78
  readonly searchable?: boolean;
76
79
  readonly sortable?: boolean;
@@ -92,6 +95,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
92
95
  readonly type: "text";
93
96
  readonly description?: string;
94
97
  readonly maxLength?: number;
98
+ readonly minLength?: number;
95
99
  readonly required?: boolean;
96
100
  readonly searchable?: boolean;
97
101
  readonly sortable?: boolean;
@@ -137,10 +141,10 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
137
141
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
138
142
  readonly display?: "radio" | "dropdown";
139
143
  readonly optionTones?: {
140
- readonly html?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
141
- readonly markdown?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
142
- readonly mjml?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
143
- readonly plain?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
144
+ readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
145
+ readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
146
+ readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
147
+ readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
144
148
  } | undefined;
145
149
  readonly optionsQuery?: string;
146
150
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -192,8 +196,8 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
192
196
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
193
197
  readonly display?: "radio" | "dropdown";
194
198
  readonly optionTones?: {
195
- readonly system?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
196
- readonly tenant?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
199
+ readonly system?: "bad" | "neutral" | "ok" | "warn" | undefined;
200
+ readonly tenant?: "bad" | "neutral" | "ok" | "warn" | undefined;
197
201
  } | undefined;
198
202
  readonly optionsQuery?: string;
199
203
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -205,6 +209,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
205
209
  readonly type: "text";
206
210
  readonly description?: string;
207
211
  readonly maxLength?: number;
212
+ readonly minLength?: number;
208
213
  readonly required?: boolean;
209
214
  readonly searchable?: boolean;
210
215
  readonly sortable?: boolean;
@@ -234,9 +239,9 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
234
239
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
235
240
  readonly display?: "radio" | "dropdown";
236
241
  readonly optionTones?: {
237
- readonly active?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
238
- readonly archived?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
239
- readonly draft?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
242
+ readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
243
+ readonly archived?: "bad" | "neutral" | "ok" | "warn" | undefined;
244
+ readonly draft?: "bad" | "neutral" | "ok" | "warn" | undefined;
240
245
  } | undefined;
241
246
  readonly optionsQuery?: string;
242
247
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -250,6 +255,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
250
255
  readonly type: "text";
251
256
  readonly description?: string;
252
257
  readonly maxLength?: number;
258
+ readonly minLength?: number;
253
259
  readonly required?: boolean;
254
260
  readonly searchable?: boolean;
255
261
  readonly sortable?: boolean;
@@ -279,12 +285,12 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
279
285
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
280
286
  readonly display?: "radio" | "dropdown";
281
287
  readonly optionTones?: {
282
- readonly "ai-prompt"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
283
- readonly "document-pdf"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
284
- readonly "image-snapshot"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
285
- readonly "mail-html"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
286
- readonly notification?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
287
- readonly "text-block"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
288
+ readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
289
+ readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
290
+ readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
291
+ readonly "mail-html"?: "bad" | "neutral" | "ok" | "warn" | undefined;
292
+ readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
293
+ readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
288
294
  } | undefined;
289
295
  readonly optionsQuery?: string;
290
296
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -296,6 +302,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
296
302
  readonly type: "text";
297
303
  readonly description?: string;
298
304
  readonly maxLength?: number;
305
+ readonly minLength?: number;
299
306
  readonly required?: boolean;
300
307
  readonly searchable?: boolean;
301
308
  readonly sortable?: boolean;
@@ -317,6 +324,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
317
324
  readonly type: "text";
318
325
  readonly description?: string;
319
326
  readonly maxLength?: number;
327
+ readonly minLength?: number;
320
328
  readonly required?: boolean;
321
329
  readonly searchable?: boolean;
322
330
  readonly sortable?: boolean;
@@ -338,6 +346,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
338
346
  readonly type: "text";
339
347
  readonly description?: string;
340
348
  readonly maxLength?: number;
349
+ readonly minLength?: number;
341
350
  readonly required?: boolean;
342
351
  readonly searchable?: boolean;
343
352
  readonly sortable?: boolean;
@@ -383,10 +392,10 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
383
392
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
384
393
  readonly display?: "radio" | "dropdown";
385
394
  readonly optionTones?: {
386
- readonly html?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
387
- readonly markdown?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
388
- readonly mjml?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
389
- readonly plain?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
395
+ readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
396
+ readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
397
+ readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
398
+ readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
390
399
  } | undefined;
391
400
  readonly optionsQuery?: string;
392
401
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -438,8 +447,8 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
438
447
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
439
448
  readonly display?: "radio" | "dropdown";
440
449
  readonly optionTones?: {
441
- readonly system?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
442
- readonly tenant?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
450
+ readonly system?: "bad" | "neutral" | "ok" | "warn" | undefined;
451
+ readonly tenant?: "bad" | "neutral" | "ok" | "warn" | undefined;
443
452
  } | undefined;
444
453
  readonly optionsQuery?: string;
445
454
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -451,6 +460,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
451
460
  readonly type: "text";
452
461
  readonly description?: string;
453
462
  readonly maxLength?: number;
463
+ readonly minLength?: number;
454
464
  readonly required?: boolean;
455
465
  readonly searchable?: boolean;
456
466
  readonly sortable?: boolean;
@@ -480,9 +490,9 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
480
490
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
481
491
  readonly display?: "radio" | "dropdown";
482
492
  readonly optionTones?: {
483
- readonly active?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
484
- readonly archived?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
485
- readonly draft?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
493
+ readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
494
+ readonly archived?: "bad" | "neutral" | "ok" | "warn" | undefined;
495
+ readonly draft?: "bad" | "neutral" | "ok" | "warn" | undefined;
486
496
  } | undefined;
487
497
  readonly optionsQuery?: string;
488
498
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -4,6 +4,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
4
4
  readonly type: "text";
5
5
  readonly description?: string;
6
6
  readonly maxLength?: number;
7
+ readonly minLength?: number;
7
8
  readonly required?: boolean;
8
9
  readonly searchable?: boolean;
9
10
  readonly sortable?: boolean;
@@ -25,6 +26,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
25
26
  readonly type: "text";
26
27
  readonly description?: string;
27
28
  readonly maxLength?: number;
29
+ readonly minLength?: number;
28
30
  readonly required?: boolean;
29
31
  readonly searchable?: boolean;
30
32
  readonly sortable?: boolean;
@@ -54,12 +56,12 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
54
56
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
55
57
  readonly display?: "radio" | "dropdown";
56
58
  readonly optionTones?: {
57
- readonly "ai-prompt"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
58
- readonly "document-pdf"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
59
- readonly "image-snapshot"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
60
- readonly "mail-html"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
61
- readonly notification?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
62
- readonly "text-block"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
59
+ readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
60
+ readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
61
+ readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
62
+ readonly "mail-html"?: "bad" | "neutral" | "ok" | "warn" | undefined;
63
+ readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
64
+ readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
63
65
  } | undefined;
64
66
  readonly optionsQuery?: string;
65
67
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -71,6 +73,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
71
73
  readonly type: "text";
72
74
  readonly description?: string;
73
75
  readonly maxLength?: number;
76
+ readonly minLength?: number;
74
77
  readonly required?: boolean;
75
78
  readonly searchable?: boolean;
76
79
  readonly sortable?: boolean;
@@ -92,6 +95,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
92
95
  readonly type: "text";
93
96
  readonly description?: string;
94
97
  readonly maxLength?: number;
98
+ readonly minLength?: number;
95
99
  readonly required?: boolean;
96
100
  readonly searchable?: boolean;
97
101
  readonly sortable?: boolean;
@@ -113,6 +117,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
113
117
  readonly type: "text";
114
118
  readonly description?: string;
115
119
  readonly maxLength?: number;
120
+ readonly minLength?: number;
116
121
  readonly required?: boolean;
117
122
  readonly searchable?: boolean;
118
123
  readonly sortable?: boolean;
@@ -158,10 +163,10 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
158
163
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
159
164
  readonly display?: "radio" | "dropdown";
160
165
  readonly optionTones?: {
161
- readonly html?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
162
- readonly markdown?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
163
- readonly mjml?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
164
- readonly plain?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
166
+ readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
167
+ readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
168
+ readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
169
+ readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
165
170
  } | undefined;
166
171
  readonly optionsQuery?: string;
167
172
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -175,6 +180,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
175
180
  readonly type: "text";
176
181
  readonly description?: string;
177
182
  readonly maxLength?: number;
183
+ readonly minLength?: number;
178
184
  readonly required?: boolean;
179
185
  readonly searchable?: boolean;
180
186
  readonly sortable?: boolean;
@@ -196,6 +202,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
196
202
  readonly type: "text";
197
203
  readonly description?: string;
198
204
  readonly maxLength?: number;
205
+ readonly minLength?: number;
199
206
  readonly required?: boolean;
200
207
  readonly searchable?: boolean;
201
208
  readonly sortable?: boolean;
@@ -225,12 +232,12 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
225
232
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
226
233
  readonly display?: "radio" | "dropdown";
227
234
  readonly optionTones?: {
228
- readonly "ai-prompt"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
229
- readonly "document-pdf"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
230
- readonly "image-snapshot"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
231
- readonly "mail-html"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
232
- readonly notification?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
233
- readonly "text-block"?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
235
+ readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
236
+ readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
237
+ readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
238
+ readonly "mail-html"?: "bad" | "neutral" | "ok" | "warn" | undefined;
239
+ readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
240
+ readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
234
241
  } | undefined;
235
242
  readonly optionsQuery?: string;
236
243
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -242,6 +249,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
242
249
  readonly type: "text";
243
250
  readonly description?: string;
244
251
  readonly maxLength?: number;
252
+ readonly minLength?: number;
245
253
  readonly required?: boolean;
246
254
  readonly searchable?: boolean;
247
255
  readonly sortable?: boolean;
@@ -263,6 +271,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
263
271
  readonly type: "text";
264
272
  readonly description?: string;
265
273
  readonly maxLength?: number;
274
+ readonly minLength?: number;
266
275
  readonly required?: boolean;
267
276
  readonly searchable?: boolean;
268
277
  readonly sortable?: boolean;
@@ -284,6 +293,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
284
293
  readonly type: "text";
285
294
  readonly description?: string;
286
295
  readonly maxLength?: number;
296
+ readonly minLength?: number;
287
297
  readonly required?: boolean;
288
298
  readonly searchable?: boolean;
289
299
  readonly sortable?: boolean;
@@ -329,10 +339,10 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
329
339
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
330
340
  readonly display?: "radio" | "dropdown";
331
341
  readonly optionTones?: {
332
- readonly html?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
333
- readonly markdown?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
334
- readonly mjml?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
335
- readonly plain?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
342
+ readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
343
+ readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
344
+ readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
345
+ readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
336
346
  } | undefined;
337
347
  readonly optionsQuery?: string;
338
348
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -0,0 +1,3 @@
1
+ export declare function decryptTenantNames<T extends {
2
+ readonly name?: unknown;
3
+ }>(rows: readonly T[], fallbackRequestId: string): Promise<T[]>;
@@ -0,0 +1,10 @@
1
+ import { decryptStoredPii, mapWithConcurrency } from "../shared/index.js";
2
+ // Bounded like tenant:query:members: each decrypt hits the KMS adapter's small pool.
3
+ const KMS_POOL_CONCURRENCY = 4;
4
+ // Raw reads of read_tenants return the stored column, which is ciphertext
5
+ // under an active KMS; executor reads (crud.list/detail) decrypt on their own.
6
+ export async function decryptTenantNames(rows, fallbackRequestId) {
7
+ return mapWithConcurrency(rows, KMS_POOL_CONCURRENCY, async (row) => typeof row.name === "string"
8
+ ? { ...row, name: await decryptStoredPii(row.name, "name", fallbackRequestId) }
9
+ : row);
10
+ }
@@ -2,6 +2,7 @@ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
5
+ import { decryptTenantNames } from "../decrypt-tenant-names.js";
5
6
  import { tenantTable } from "../schema/tenant.js";
6
7
  // Direct query — query handlers don't have a tenant-crud handle. A direct
7
8
  // select is trivial: WHERE id = tenantId (both UUID). No CRUD detour needed.
@@ -28,6 +29,9 @@ export const meQuery = defineQueryHandler({
28
29
  }
29
30
  const db = ctx.systemDb.assertTenantMatch(query.user.tenantId);
30
31
  const row = await fetchOne(db, tenantTable, { id: query.user.tenantId });
31
- return row ?? null;
32
+ if (row === undefined)
33
+ return null;
34
+ const [decrypted] = await decryptTenantNames([row], "tenant:me");
35
+ return decrypted ?? null;
32
36
  },
33
37
  });
@@ -3,6 +3,7 @@ import { defineQueryHandler, SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/e
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
5
5
  import * as z from "zod";
6
+ import { decryptTenantNames } from "../decrypt-tenant-names.js";
6
7
  import { tenantMembershipsTable } from "../membership-table.js";
7
8
  import { tenantTable } from "../schema/tenant.js";
8
9
  export const membershipsQuery = defineQueryHandler({
@@ -22,9 +23,9 @@ export const membershipsQuery = defineQueryHandler({
22
23
  const rows = await selectMany(db, tenantMembershipsTable, { userId: query.payload.userId });
23
24
  if (rows.length === 0)
24
25
  return [];
25
- const tenants = await selectMany(db, tenantTable, {
26
+ const tenants = await decryptTenantNames(await selectMany(db, tenantTable, {
26
27
  id: rows.map((row) => row["tenantId"]),
27
- });
28
+ }), "tenant:memberships");
28
29
  const tenantById = new Map(tenants.map((t) => [t.id, t]));
29
30
  return rows
30
31
  .map((row) => {
@@ -2,6 +2,7 @@ import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
2
  import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
5
+ import { decryptTenantNames } from "../decrypt-tenant-names.js";
5
6
  import { tenantTable } from "../schema/tenant.js";
6
7
  import { isSystemAdmin } from "./is-system-admin.js";
7
8
  // Label source behind every `tenant:tenant` reference column (fw#3142). The
@@ -38,7 +39,7 @@ export const tenantDirectoryQuery = definePagedQueryHandler({
38
39
  tenants = await selectMany(db, tenantTable, undefined, {
39
40
  limit: scanLimit,
40
41
  orderBy: [
41
- { col: "name", direction: "asc" },
42
+ { col: "key", direction: "asc" },
42
43
  { col: "id", direction: "asc" },
43
44
  ],
44
45
  });
@@ -48,10 +49,15 @@ export const tenantDirectoryQuery = definePagedQueryHandler({
48
49
  const row = await fetchOne(db, tenantTable, { id: query.user.tenantId });
49
50
  tenants = row ? [row] : [];
50
51
  }
51
- const labeled = tenants.map((tenant) => {
52
+ // name is ciphertext at rest, so the SQL page is keyed by the plaintext
53
+ // `key`; label order and search happen in memory after decrypting.
54
+ const decrypted = await decryptTenantNames(tenants, "tenant:tenant-directory");
55
+ const labeled = decrypted
56
+ .map((tenant) => {
52
57
  const id = String(tenant.id);
53
58
  return { id, label: typeof tenant.name === "string" ? tenant.name : id };
54
- });
59
+ })
60
+ .sort((a, b) => a.label.localeCompare(b.label) || a.id.localeCompare(b.id));
55
61
  const needle = search?.toLowerCase();
56
62
  const rows = needle === undefined
57
63
  ? labeled
@@ -1,6 +1,7 @@
1
1
  export { cancelPendingInvitation } from "./cancel-pending-invitation.js";
2
2
  export { TenantCommandSchemas } from "./command-schemas.js";
3
3
  export { OWNER_INVITE_ROLE_OPTIONS, TENANT_FEATURE, TenantErrors, TenantHandlers, TenantQueries, } from "./constants.js";
4
+ export { decryptTenantNames } from "./decrypt-tenant-names.js";
4
5
  export { collectAssignableAppRoles, createTenantFeature } from "./feature.js";
5
6
  export type { InvitationStatus } from "./invitation-table.js";
6
7
  export { INVITATION_STATUS, INVITATION_STATUSES, tenantInvitationEntity, tenantInvitationsTable, } from "./invitation-table.js";
@@ -1,6 +1,7 @@
1
1
  export { cancelPendingInvitation } from "./cancel-pending-invitation.js";
2
2
  export { TenantCommandSchemas } from "./command-schemas.js";
3
3
  export { OWNER_INVITE_ROLE_OPTIONS, TENANT_FEATURE, TenantErrors, TenantHandlers, TenantQueries, } from "./constants.js";
4
+ export { decryptTenantNames } from "./decrypt-tenant-names.js";
4
5
  export { collectAssignableAppRoles, createTenantFeature } from "./feature.js";
5
6
  export { INVITATION_STATUS, INVITATION_STATUSES, tenantInvitationEntity, tenantInvitationsTable, } from "./invitation-table.js";
6
7
  export { isTenantServingPublicContent } from "./is-tenant-serving-public-content.js";
@@ -11,6 +11,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
11
11
  readonly type: "text";
12
12
  readonly description?: string;
13
13
  readonly maxLength?: number;
14
+ readonly minLength?: number;
14
15
  readonly required?: boolean;
15
16
  readonly searchable?: boolean;
16
17
  readonly sortable?: boolean;
@@ -32,6 +33,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
32
33
  readonly type: "text";
33
34
  readonly description?: string;
34
35
  readonly maxLength?: number;
36
+ readonly minLength?: number;
35
37
  readonly required?: boolean;
36
38
  readonly searchable?: boolean;
37
39
  readonly sortable?: boolean;
@@ -62,10 +64,10 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
62
64
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
63
65
  readonly display?: "radio" | "dropdown";
64
66
  readonly optionTones?: {
65
- readonly accepted?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
66
- readonly cancelled?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
67
- readonly expired?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
68
- readonly pending?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
67
+ readonly accepted?: "bad" | "neutral" | "ok" | "warn" | undefined;
68
+ readonly cancelled?: "bad" | "neutral" | "ok" | "warn" | undefined;
69
+ readonly expired?: "bad" | "neutral" | "ok" | "warn" | undefined;
70
+ readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
69
71
  } | undefined;
70
72
  readonly optionsQuery?: string;
71
73
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -77,6 +79,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
77
79
  readonly type: "text";
78
80
  readonly description?: string;
79
81
  readonly maxLength?: number;
82
+ readonly minLength?: number;
80
83
  readonly required?: boolean;
81
84
  readonly searchable?: boolean;
82
85
  readonly sortable?: boolean;
@@ -115,6 +118,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
115
118
  readonly type: "text";
116
119
  readonly description?: string;
117
120
  readonly maxLength?: number;
121
+ readonly minLength?: number;
118
122
  readonly required?: boolean;
119
123
  readonly searchable?: boolean;
120
124
  readonly sortable?: boolean;
@@ -136,6 +140,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
136
140
  readonly type: "text";
137
141
  readonly description?: string;
138
142
  readonly maxLength?: number;
143
+ readonly minLength?: number;
139
144
  readonly required?: boolean;
140
145
  readonly searchable?: boolean;
141
146
  readonly sortable?: boolean;
@@ -166,10 +171,10 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
166
171
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
167
172
  readonly display?: "radio" | "dropdown";
168
173
  readonly optionTones?: {
169
- readonly accepted?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
170
- readonly cancelled?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
171
- readonly expired?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
172
- readonly pending?: import("@cosmicdrift/kumiko-types/fields").SelectOptionTone | undefined;
174
+ readonly accepted?: "bad" | "neutral" | "ok" | "warn" | undefined;
175
+ readonly cancelled?: "bad" | "neutral" | "ok" | "warn" | undefined;
176
+ readonly expired?: "bad" | "neutral" | "ok" | "warn" | undefined;
177
+ readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
173
178
  } | undefined;
174
179
  readonly optionsQuery?: string;
175
180
  readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
@@ -181,6 +186,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
181
186
  readonly type: "text";
182
187
  readonly description?: string;
183
188
  readonly maxLength?: number;
189
+ readonly minLength?: number;
184
190
  readonly required?: boolean;
185
191
  readonly searchable?: boolean;
186
192
  readonly sortable?: boolean;
@@ -3,6 +3,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
3
3
  readonly type: "text";
4
4
  readonly description?: string;
5
5
  readonly maxLength?: number;
6
+ readonly minLength?: number;
6
7
  readonly required?: boolean;
7
8
  readonly searchable?: boolean;
8
9
  readonly sortable?: boolean;
@@ -24,6 +25,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
24
25
  readonly type: "text";
25
26
  readonly description?: string;
26
27
  readonly maxLength?: number;
28
+ readonly minLength?: number;
27
29
  readonly required?: boolean;
28
30
  readonly searchable?: boolean;
29
31
  readonly sortable?: boolean;
@@ -47,6 +49,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
47
49
  readonly type: "text";
48
50
  readonly description?: string;
49
51
  readonly maxLength?: number;
52
+ readonly minLength?: number;
50
53
  readonly required?: boolean;
51
54
  readonly searchable?: boolean;
52
55
  readonly sortable?: boolean;
@@ -68,6 +71,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
68
71
  readonly type: "text";
69
72
  readonly description?: string;
70
73
  readonly maxLength?: number;
74
+ readonly minLength?: number;
71
75
  readonly required?: boolean;
72
76
  readonly searchable?: boolean;
73
77
  readonly sortable?: boolean;