@cosmicdrift/kumiko-bundled-features 0.355.0 → 0.357.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 (88) hide show
  1. package/dist/auth-mfa/i18n.js +1 -0
  2. package/dist/auth-mfa/schema/user-mfa.d.ts +6 -0
  3. package/dist/auth-mfa/screens.js +8 -1
  4. package/dist/billing-foundation/entities.d.ts +8 -0
  5. package/dist/billing-foundation/projection.d.ts +8 -0
  6. package/dist/cap-counter/entity.d.ts +1 -0
  7. package/dist/cap-counter/feature.js +7 -1
  8. package/dist/cap-overview/screens.js +3 -1
  9. package/dist/compliance-profiles/handlers/set-profile.write.js +14 -22
  10. package/dist/config/table.d.ts +6 -0
  11. package/dist/crypto-shredding/handlers/forget-subject.write.js +15 -3
  12. package/dist/custom-fields/entity.d.ts +4 -0
  13. package/dist/custom-fields/handlers/define-system-field.write.js +8 -16
  14. package/dist/custom-fields/handlers/delete-system-field.write.js +5 -2
  15. package/dist/custom-fields/lib/define-or-resurrect.d.ts +2 -1
  16. package/dist/custom-fields/lib/define-or-resurrect.js +11 -4
  17. package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -0
  18. package/dist/delivery/chat-webhook-sender.js +1 -1
  19. package/dist/delivery/constants.d.ts +1 -0
  20. package/dist/delivery/constants.js +4 -0
  21. package/dist/delivery/delivery-service.js +62 -25
  22. package/dist/delivery/feature.js +7 -1
  23. package/dist/delivery/jobs.js +25 -1
  24. package/dist/delivery/tables.d.ts +6 -0
  25. package/dist/delivery/testing.d.ts +1 -0
  26. package/dist/document-ingest-foundation/entity.d.ts +4 -0
  27. package/dist/folders/entity.d.ts +8 -0
  28. package/dist/form-draft/entity.d.ts +2 -0
  29. package/dist/inbound-mail-foundation/entities.d.ts +25 -0
  30. package/dist/inbound-mail-foundation/projection.d.ts +20 -0
  31. package/dist/jobs/job-run-table.d.ts +6 -0
  32. package/dist/ledger/entity.d.ts +13 -0
  33. package/dist/managed-pages/handlers/set.write.js +6 -17
  34. package/dist/managed-pages/table.d.ts +12 -0
  35. package/dist/notes-history/entity.d.ts +12 -0
  36. package/dist/notes-history/entity.js +7 -6
  37. package/dist/notes-history-user-data/hooks.d.ts +10 -1
  38. package/dist/notes-history-user-data/hooks.js +78 -61
  39. package/dist/notes-history-user-data/index.d.ts +1 -0
  40. package/dist/notes-history-user-data/index.js +2 -1
  41. package/dist/personal-access-tokens/schema/api-token.d.ts +6 -0
  42. package/dist/personal-access-tokens/screens.js +2 -0
  43. package/dist/secrets/table.d.ts +1 -0
  44. package/dist/sessions/schema/user-session.d.ts +4 -0
  45. package/dist/sessions/screens.js +2 -0
  46. package/dist/shared/index.d.ts +1 -0
  47. package/dist/shared/index.js +1 -0
  48. package/dist/shared/require-for-tenant.d.ts +2 -0
  49. package/dist/shared/require-for-tenant.js +9 -0
  50. package/dist/tags/entity.d.ts +9 -0
  51. package/dist/template-resolver/handlers/collection-set.write.js +4 -4
  52. package/dist/template-resolver/handlers/set.write.js +6 -7
  53. package/dist/template-resolver/handlers/upsert-system.write.js +6 -6
  54. package/dist/template-resolver/handlers/upsert-tenant.write.js +6 -4
  55. package/dist/template-resolver/table.d.ts +10 -0
  56. package/dist/template-resolver/user-content-table.d.ts +10 -0
  57. package/dist/tenant/cancel-pending-invitation.d.ts +2 -2
  58. package/dist/tenant/cancel-pending-invitation.js +2 -2
  59. package/dist/tenant/constants.d.ts +1 -0
  60. package/dist/tenant/constants.js +6 -3
  61. package/dist/tenant/feature.js +2 -0
  62. package/dist/tenant/handlers/member-role-availability.query.d.ts +7 -0
  63. package/dist/tenant/handlers/member-role-availability.query.js +18 -0
  64. package/dist/tenant/handlers/remove-member.write.js +13 -10
  65. package/dist/tenant/handlers/update-member-roles.write.js +12 -9
  66. package/dist/tenant/invitation-table.d.ts +6 -0
  67. package/dist/tenant/member-role-options.d.ts +2 -0
  68. package/dist/tenant/member-role-options.js +4 -0
  69. package/dist/tenant/membership-table.d.ts +4 -0
  70. package/dist/tenant/schema/tenant.d.ts +6 -0
  71. package/dist/tenant/screens.d.ts +4 -2
  72. package/dist/tenant/screens.js +10 -6
  73. package/dist/tier-engine/entity.d.ts +2 -0
  74. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -18
  75. package/dist/tier-engine/tier-resolver.d.ts +2 -0
  76. package/dist/user/schema/user.d.ts +12 -0
  77. package/dist/user/screens.js +8 -1
  78. package/dist/user-data-rights/schema/download-attempt.d.ts +14 -0
  79. package/dist/user-data-rights/schema/download-token.d.ts +8 -0
  80. package/dist/user-data-rights/schema/export-job.d.ts +6 -0
  81. package/dist/user-data-rights/screens.js +8 -1
  82. package/dist/waitlist/entity.d.ts +14 -0
  83. package/dist/waitlist/screens.js +8 -1
  84. package/package.json +9 -9
  85. package/src/auth-mfa/changes.json +6 -0
  86. package/src/crypto-shredding/changes.json +6 -0
  87. package/src/delivery/changes.json +6 -0
  88. package/src/tenant/changes.json +6 -0
@@ -8,7 +8,7 @@ import { redactErrorText } from "../shared/index.js";
8
8
  import { hashUnsubscribeAddress } from "./address-opt-out.js";
9
9
  import { appendAttemptEvent, logAttempt } from "./attempt-log.js";
10
10
  import { buildChannelContext } from "./channel-context.js";
11
- import { DELIVERY_CHANNEL_EXTENSION, DeliveryJobs, deliveryPriorityRank } from "./constants.js";
11
+ import { DELIVERY_CHANNEL_EXTENSION, DeliveryJobs, deliveryIdempotencyRedisKey, deliveryPriorityRank, } from "./constants.js";
12
12
  import { addressOptOutKey, selectOptedOutAddresses, } from "./db/queries/address-opt-outs.js";
13
13
  import { selectNotificationPreferences } from "./db/queries/preferences.js";
14
14
  import { isDeliveryChannelPlugin, } from "./types.js";
@@ -74,10 +74,28 @@ export function createDeliveryService(options) {
74
74
  if (!idemRedis) {
75
75
  throw new Error("Delivery idempotencyKey requires options.idempotencyRedis (or rateLimit.redis) to be configured");
76
76
  }
77
- const k = `delivery:idem:${tenantId}:${key}`;
78
- const res = await idemRedis.set(k, "1", "EX", ttlSec, "NX");
77
+ const res = await idemRedis.set(deliveryIdempotencyRedisKey(tenantId, key), "1", "EX", ttlSec, "NX");
79
78
  return res === "OK";
80
79
  }
80
+ function isDeliveredOrQueued(delivery) {
81
+ return delivery.status === "sent" || delivery.status === "queued";
82
+ }
83
+ // A key that guarded nothing must not turn the caller's retry into a skipped duplicate.
84
+ // Partial success keeps it: a retry would re-send to those who got it.
85
+ async function releaseIdempotencyIfNothingDelivered(tenantId, key, run) {
86
+ // skip: no key claimed, or a recipient already got the notification
87
+ if (!key || run.deliveries.some(isDeliveredOrQueued))
88
+ return;
89
+ await idemRedis?.del(deliveryIdempotencyRedisKey(tenantId, key));
90
+ }
91
+ // Only a single-channel route lets the queued job free the key on terminal failure
92
+ // without risking a duplicate send on another channel.
93
+ function jobIdempotencyKeyFor(idempotencyKey, route) {
94
+ if (!idempotencyKey || !route)
95
+ return undefined;
96
+ const routedChannelCount = channels.filter((channel) => route[channel.name]).length;
97
+ return routedChannelCount === 1 ? idempotencyKey : undefined;
98
+ }
81
99
  async function resolveUserIdsForTenant(tenantId) {
82
100
  if (!tenantUserIdsQuery) {
83
101
  throw new Error("Tenant broadcast requires tenantUserIdsQuery in DeliveryServiceOptions");
@@ -191,6 +209,7 @@ export function createDeliveryService(options) {
191
209
  deliveryAttemptId,
192
210
  priority,
193
211
  message,
212
+ ...(run.jobIdempotencyKey !== undefined && { idempotencyKey: run.jobIdempotencyKey }),
194
213
  }, { priority: deliveryPriorityRank[priority] });
195
214
  recordDelivery(run, queuedEntry, deliveryAttemptId);
196
215
  }
@@ -517,14 +536,42 @@ export function createDeliveryService(options) {
517
536
  }
518
537
  }
519
538
  }
539
+ async function dispatchNotification(notificationType, options, tenantId, priority, run) {
540
+ const { to, route, data } = options;
541
+ if (route) {
542
+ await deliverDirect(route, notificationType, data, tenantId, priority, options.recipientId ?? null, run);
543
+ // skip: explicit route is delivered directly, no recipient resolution needed
544
+ return;
545
+ }
546
+ if (to !== undefined) {
547
+ let userIds;
548
+ if (typeof to === "string") {
549
+ userIds = [to];
550
+ }
551
+ else if ("tenant" in to) {
552
+ userIds = await resolveUserIdsForTenant(to.tenant);
553
+ }
554
+ else {
555
+ userIds = to;
556
+ }
557
+ const prefetchedAddresses = priority === "critical"
558
+ ? new Map()
559
+ : await prefetchUserAddresses(userIds, tenantId, notificationType);
560
+ const suppressed = await loadSuppressedAddresses(tenantId, notificationType, priority, [...prefetchedAddresses.values()].filter((address) => !!address));
561
+ for (const userId of userIds) {
562
+ await deliverToUser(userId, notificationType, data, tenantId, priority, run, prefetchedAddresses, suppressed);
563
+ }
564
+ }
565
+ }
520
566
  return {
521
567
  async notify(notificationType, options, _user, tenantId, jobDispatcher) {
522
- const { to, route, data, idempotencyKey } = options;
568
+ const { route, idempotencyKey } = options;
523
569
  const priority = options.priority ?? "normal";
524
570
  const run = {
525
571
  deliveries: [],
526
572
  jobDispatcher: options.immediate ? undefined : (jobDispatcher ?? jobRunner),
527
573
  locale: options.locale,
574
+ jobIdempotencyKey: jobIdempotencyKeyFor(idempotencyKey, route),
528
575
  };
529
576
  if (idempotencyKey) {
530
577
  const first = await claimIdempotency(tenantId, idempotencyKey);
@@ -542,29 +589,19 @@ export function createDeliveryService(options) {
542
589
  return { deliveries: run.deliveries };
543
590
  }
544
591
  }
545
- if (route) {
546
- await deliverDirect(route, notificationType, data, tenantId, priority, options.recipientId ?? null, run);
547
- return { deliveries: run.deliveries };
592
+ try {
593
+ await dispatchNotification(notificationType, options, tenantId, priority, run);
548
594
  }
549
- if (to !== undefined) {
550
- let userIds;
551
- if (typeof to === "string") {
552
- userIds = [to];
553
- }
554
- else if ("tenant" in to) {
555
- userIds = await resolveUserIdsForTenant(to.tenant);
556
- }
557
- else {
558
- userIds = to;
559
- }
560
- const prefetchedAddresses = priority === "critical"
561
- ? new Map()
562
- : await prefetchUserAddresses(userIds, tenantId, notificationType);
563
- const suppressed = await loadSuppressedAddresses(tenantId, notificationType, priority, [...prefetchedAddresses.values()].filter((address) => !!address));
564
- for (const userId of userIds) {
565
- await deliverToUser(userId, notificationType, data, tenantId, priority, run, prefetchedAddresses, suppressed);
566
- }
595
+ catch (err) {
596
+ // A failing release must not replace the dispatch error the caller retries on.
597
+ await releaseIdempotencyIfNothingDelivered(tenantId, idempotencyKey, run).catch((releaseErr) => {
598
+ logError.warn(`idempotency key release failed: ${redactedMessageOf(releaseErr)}`, {
599
+ notificationType,
600
+ });
601
+ });
602
+ throw err;
567
603
  }
604
+ await releaseIdempotencyIfNothingDelivered(tenantId, idempotencyKey, run);
568
605
  return { deliveries: run.deliveries };
569
606
  },
570
607
  };
@@ -179,15 +179,21 @@ export function createDeliveryFeature(options) {
179
179
  label: i18nKey("delivery.log.col.channel"),
180
180
  renderer: { react: { __component: DELIVERY_CHANNEL_CELL_COMPONENT } },
181
181
  },
182
- { field: "recipientLabel", label: i18nKey("delivery.log.col.recipient") },
182
+ {
183
+ field: "recipientLabel",
184
+ label: i18nKey("delivery.log.col.recipient"),
185
+ hideOnNarrow: true,
186
+ },
183
187
  {
184
188
  field: "status",
185
189
  label: i18nKey("delivery.log.col.status"),
190
+ hideOnNarrow: true,
186
191
  renderer: { react: { __component: DELIVERY_STATUS_CELL_COMPONENT } },
187
192
  },
188
193
  {
189
194
  field: "error",
190
195
  label: i18nKey("delivery.log.col.error"),
196
+ hideOnNarrow: true,
191
197
  renderer: { react: { __component: DELIVERY_ERROR_CELL_COMPONENT } },
192
198
  },
193
199
  ],
@@ -8,7 +8,7 @@ import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
8
8
  import * as z from "zod";
9
9
  import { appendAttemptEvent } from "./attempt-log.js";
10
10
  import { buildChannelContext } from "./channel-context.js";
11
- import { DeliveryJobs, deliveryPriorityRank } from "./constants.js";
11
+ import { DeliveryJobs, deliveryIdempotencyRedisKey, deliveryPriorityRank } from "./constants.js";
12
12
  import { collectChannels, redactedMessageOf } from "./delivery-service.js";
13
13
  const channelMessageSchema = z.object({
14
14
  notificationType: z.string(),
@@ -26,6 +26,7 @@ const renderJobPayloadSchema = z.object({
26
26
  deliveryAttemptId: z.string(),
27
27
  priority: z.enum(["critical", "normal", "low"]),
28
28
  message: channelMessageSchema,
29
+ idempotencyKey: z.string().optional(),
29
30
  });
30
31
  const sendJobPayloadSchema = renderJobPayloadSchema.extend({
31
32
  rendered: z
@@ -75,6 +76,28 @@ function entryFor(p, status, error, address, confirmed) {
75
76
  ...(confirmed === false && { confirmed }),
76
77
  };
77
78
  }
79
+ // Only the final retry frees the key: earlier failures are retried by the runner and
80
+ // must still dedup. Assumes ctx.redis is the handle the service claimed on; runProdApp
81
+ // wires the same instance into both.
82
+ async function releaseIdempotencyOnTerminalFailure(ctx, p) {
83
+ // skip: nothing to release before the last attempt or without an idempotency key
84
+ if (!ctx.finalAttempt || !p.idempotencyKey)
85
+ return;
86
+ if (!ctx.redis) {
87
+ ctx.log.warn("delivery: idempotency key not released, job context has no redis", {
88
+ notificationType: p.notificationType,
89
+ });
90
+ return;
91
+ }
92
+ try {
93
+ await ctx.redis.del(deliveryIdempotencyRedisKey(p.tenantId, p.idempotencyKey));
94
+ }
95
+ catch (err) {
96
+ ctx.log.warn(`delivery: idempotency key release failed: ${redactedMessageOf(err)}`, {
97
+ notificationType: p.notificationType,
98
+ });
99
+ }
100
+ }
78
101
  // The job runner stores err.message in the run row, and BullMQ keeps failedReason and
79
102
  // the stack trace in Redis in plain text, so the rethrown error carries only the code.
80
103
  // The redacted message goes to the log.
@@ -85,6 +108,7 @@ async function failAttempt(ctx, db, registry, p, code, err) {
85
108
  channel: p.channelName,
86
109
  });
87
110
  await appendAttemptEvent(db, registry, p.deliveryAttemptId, entryFor(p, "failed", code, p.address));
111
+ await releaseIdempotencyOnTerminalFailure(ctx, p);
88
112
  throw new Error(code);
89
113
  }
90
114
  // Render the message and hand off to delivery.send. On failure: record the
@@ -7,6 +7,7 @@ export declare const notificationPreferenceEntity: import("@cosmicdrift/kumiko-t
7
7
  readonly description?: string;
8
8
  readonly maxLength?: number;
9
9
  readonly minLength?: number;
10
+ readonly autoComplete?: string;
10
11
  readonly required?: boolean;
11
12
  readonly searchable?: boolean;
12
13
  readonly sortable?: boolean;
@@ -29,6 +30,7 @@ export declare const notificationPreferenceEntity: import("@cosmicdrift/kumiko-t
29
30
  readonly description?: string;
30
31
  readonly maxLength?: number;
31
32
  readonly minLength?: number;
33
+ readonly autoComplete?: string;
32
34
  readonly required?: boolean;
33
35
  readonly searchable?: boolean;
34
36
  readonly sortable?: boolean;
@@ -51,6 +53,7 @@ export declare const notificationPreferenceEntity: import("@cosmicdrift/kumiko-t
51
53
  readonly description?: string;
52
54
  readonly maxLength?: number;
53
55
  readonly minLength?: number;
56
+ readonly autoComplete?: string;
54
57
  readonly required?: boolean;
55
58
  readonly searchable?: boolean;
56
59
  readonly sortable?: boolean;
@@ -79,6 +82,7 @@ export declare const notificationAddressOptOutEntity: import("@cosmicdrift/kumik
79
82
  readonly description?: string;
80
83
  readonly maxLength?: number;
81
84
  readonly minLength?: number;
85
+ readonly autoComplete?: string;
82
86
  readonly required?: boolean;
83
87
  readonly searchable?: boolean;
84
88
  readonly sortable?: boolean;
@@ -101,6 +105,7 @@ export declare const notificationAddressOptOutEntity: import("@cosmicdrift/kumik
101
105
  readonly description?: string;
102
106
  readonly maxLength?: number;
103
107
  readonly minLength?: number;
108
+ readonly autoComplete?: string;
104
109
  readonly required?: boolean;
105
110
  readonly searchable?: boolean;
106
111
  readonly sortable?: boolean;
@@ -123,6 +128,7 @@ export declare const notificationAddressOptOutEntity: import("@cosmicdrift/kumik
123
128
  readonly description?: string;
124
129
  readonly maxLength?: number;
125
130
  readonly minLength?: number;
131
+ readonly autoComplete?: string;
126
132
  readonly required?: boolean;
127
133
  readonly searchable?: boolean;
128
134
  readonly sortable?: boolean;
@@ -15,6 +15,7 @@ export type CreateDeliveryTestContextOptions = {
15
15
  readonly log?: Logger;
16
16
  readonly jobRunner?: JobRunner;
17
17
  readonly secrets?: SecretsContext;
18
+ readonly idempotencyRedis?: Redis;
18
19
  };
19
20
  /**
20
21
  * Helper for setupTestStack: creates a DeliveryService + _notifyFactory for the test context.
@@ -15,6 +15,7 @@ export declare const documentExtractEntity: import("@cosmicdrift/kumiko-types/fi
15
15
  readonly description?: string;
16
16
  readonly maxLength?: number;
17
17
  readonly minLength?: number;
18
+ readonly autoComplete?: string;
18
19
  readonly required?: boolean;
19
20
  readonly searchable?: boolean;
20
21
  readonly sortable?: boolean;
@@ -37,6 +38,7 @@ export declare const documentExtractEntity: import("@cosmicdrift/kumiko-types/fi
37
38
  readonly description?: string;
38
39
  readonly maxLength?: number;
39
40
  readonly minLength?: number;
41
+ readonly autoComplete?: string;
40
42
  readonly required?: boolean;
41
43
  readonly searchable?: boolean;
42
44
  readonly sortable?: boolean;
@@ -78,6 +80,7 @@ export declare const documentExtractsTable: import("@cosmicdrift/kumiko-framewor
78
80
  readonly description?: string;
79
81
  readonly maxLength?: number;
80
82
  readonly minLength?: number;
83
+ readonly autoComplete?: string;
81
84
  readonly required?: boolean;
82
85
  readonly searchable?: boolean;
83
86
  readonly sortable?: boolean;
@@ -100,6 +103,7 @@ export declare const documentExtractsTable: import("@cosmicdrift/kumiko-framewor
100
103
  readonly description?: string;
101
104
  readonly maxLength?: number;
102
105
  readonly minLength?: number;
106
+ readonly autoComplete?: string;
103
107
  readonly required?: boolean;
104
108
  readonly searchable?: boolean;
105
109
  readonly sortable?: boolean;
@@ -5,6 +5,7 @@ export declare const folderEntity: EntityDefinition<{
5
5
  readonly description?: string;
6
6
  readonly maxLength?: number;
7
7
  readonly minLength?: number;
8
+ readonly autoComplete?: string;
8
9
  readonly required?: boolean;
9
10
  readonly searchable?: boolean;
10
11
  readonly sortable?: boolean;
@@ -27,6 +28,7 @@ export declare const folderEntity: EntityDefinition<{
27
28
  readonly description?: string;
28
29
  readonly maxLength?: number;
29
30
  readonly minLength?: number;
31
+ readonly autoComplete?: string;
30
32
  readonly required?: boolean;
31
33
  readonly searchable?: boolean;
32
34
  readonly sortable?: boolean;
@@ -51,6 +53,7 @@ export declare function createFolderAssignmentEntity(access?: EntityDefinition["
51
53
  readonly description?: string;
52
54
  readonly maxLength?: number;
53
55
  readonly minLength?: number;
56
+ readonly autoComplete?: string;
54
57
  readonly required?: boolean;
55
58
  readonly searchable?: boolean;
56
59
  readonly sortable?: boolean;
@@ -73,6 +76,7 @@ export declare function createFolderAssignmentEntity(access?: EntityDefinition["
73
76
  readonly description?: string;
74
77
  readonly maxLength?: number;
75
78
  readonly minLength?: number;
79
+ readonly autoComplete?: string;
76
80
  readonly required?: boolean;
77
81
  readonly searchable?: boolean;
78
82
  readonly sortable?: boolean;
@@ -95,6 +99,7 @@ export declare function createFolderAssignmentEntity(access?: EntityDefinition["
95
99
  readonly description?: string;
96
100
  readonly maxLength?: number;
97
101
  readonly minLength?: number;
102
+ readonly autoComplete?: string;
98
103
  readonly required?: boolean;
99
104
  readonly searchable?: boolean;
100
105
  readonly sortable?: boolean;
@@ -119,6 +124,7 @@ export declare const folderAssignmentEntity: EntityDefinition<{
119
124
  readonly description?: string;
120
125
  readonly maxLength?: number;
121
126
  readonly minLength?: number;
127
+ readonly autoComplete?: string;
122
128
  readonly required?: boolean;
123
129
  readonly searchable?: boolean;
124
130
  readonly sortable?: boolean;
@@ -141,6 +147,7 @@ export declare const folderAssignmentEntity: EntityDefinition<{
141
147
  readonly description?: string;
142
148
  readonly maxLength?: number;
143
149
  readonly minLength?: number;
150
+ readonly autoComplete?: string;
144
151
  readonly required?: boolean;
145
152
  readonly searchable?: boolean;
146
153
  readonly sortable?: boolean;
@@ -163,6 +170,7 @@ export declare const folderAssignmentEntity: EntityDefinition<{
163
170
  readonly description?: string;
164
171
  readonly maxLength?: number;
165
172
  readonly minLength?: number;
173
+ readonly autoComplete?: string;
166
174
  readonly required?: boolean;
167
175
  readonly searchable?: boolean;
168
176
  readonly sortable?: boolean;
@@ -4,6 +4,7 @@ export declare const formDraftEntity: import("@cosmicdrift/kumiko-types/fields")
4
4
  readonly description?: string;
5
5
  readonly maxLength?: number;
6
6
  readonly minLength?: number;
7
+ readonly autoComplete?: string;
7
8
  readonly required?: boolean;
8
9
  readonly searchable?: boolean;
9
10
  readonly sortable?: boolean;
@@ -26,6 +27,7 @@ export declare const formDraftEntity: import("@cosmicdrift/kumiko-types/fields")
26
27
  readonly description?: string;
27
28
  readonly maxLength?: number;
28
29
  readonly minLength?: number;
30
+ readonly autoComplete?: string;
29
31
  readonly required?: boolean;
30
32
  readonly searchable?: boolean;
31
33
  readonly sortable?: boolean;
@@ -6,6 +6,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
6
6
  readonly description?: string;
7
7
  readonly maxLength?: number;
8
8
  readonly minLength?: number;
9
+ readonly autoComplete?: string;
9
10
  readonly required?: boolean;
10
11
  readonly searchable?: boolean;
11
12
  readonly sortable?: boolean;
@@ -28,6 +29,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
28
29
  readonly description?: string;
29
30
  readonly maxLength?: number;
30
31
  readonly minLength?: number;
32
+ readonly autoComplete?: string;
31
33
  readonly required?: boolean;
32
34
  readonly searchable?: boolean;
33
35
  readonly sortable?: boolean;
@@ -50,6 +52,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
50
52
  readonly description?: string;
51
53
  readonly maxLength?: number;
52
54
  readonly minLength?: number;
55
+ readonly autoComplete?: string;
53
56
  readonly required?: boolean;
54
57
  readonly searchable?: boolean;
55
58
  readonly sortable?: boolean;
@@ -72,6 +75,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
72
75
  readonly description?: string;
73
76
  readonly maxLength?: number;
74
77
  readonly minLength?: number;
78
+ readonly autoComplete?: string;
75
79
  readonly required?: boolean;
76
80
  readonly searchable?: boolean;
77
81
  readonly sortable?: boolean;
@@ -94,6 +98,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
94
98
  readonly description?: string;
95
99
  readonly maxLength?: number;
96
100
  readonly minLength?: number;
101
+ readonly autoComplete?: string;
97
102
  readonly required?: boolean;
98
103
  readonly searchable?: boolean;
99
104
  readonly sortable?: boolean;
@@ -116,6 +121,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
116
121
  readonly description?: string;
117
122
  readonly maxLength?: number;
118
123
  readonly minLength?: number;
124
+ readonly autoComplete?: string;
119
125
  readonly required?: boolean;
120
126
  readonly searchable?: boolean;
121
127
  readonly sortable?: boolean;
@@ -138,6 +144,7 @@ export declare const mailAccountEntity: import("@cosmicdrift/kumiko-types/fields
138
144
  readonly description?: string;
139
145
  readonly maxLength?: number;
140
146
  readonly minLength?: number;
147
+ readonly autoComplete?: string;
141
148
  readonly required?: boolean;
142
149
  readonly searchable?: boolean;
143
150
  readonly sortable?: boolean;
@@ -180,6 +187,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
180
187
  readonly description?: string;
181
188
  readonly maxLength?: number;
182
189
  readonly minLength?: number;
190
+ readonly autoComplete?: string;
183
191
  readonly required?: boolean;
184
192
  readonly searchable?: boolean;
185
193
  readonly sortable?: boolean;
@@ -202,6 +210,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
202
210
  readonly description?: string;
203
211
  readonly maxLength?: number;
204
212
  readonly minLength?: number;
213
+ readonly autoComplete?: string;
205
214
  readonly required?: boolean;
206
215
  readonly searchable?: boolean;
207
216
  readonly sortable?: boolean;
@@ -224,6 +233,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
224
233
  readonly description?: string;
225
234
  readonly maxLength?: number;
226
235
  readonly minLength?: number;
236
+ readonly autoComplete?: string;
227
237
  readonly required?: boolean;
228
238
  readonly searchable?: boolean;
229
239
  readonly sortable?: boolean;
@@ -246,6 +256,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
246
256
  readonly description?: string;
247
257
  readonly maxLength?: number;
248
258
  readonly minLength?: number;
259
+ readonly autoComplete?: string;
249
260
  readonly required?: boolean;
250
261
  readonly searchable?: boolean;
251
262
  readonly sortable?: boolean;
@@ -268,6 +279,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
268
279
  readonly description?: string;
269
280
  readonly maxLength?: number;
270
281
  readonly minLength?: number;
282
+ readonly autoComplete?: string;
271
283
  readonly required?: boolean;
272
284
  readonly searchable?: boolean;
273
285
  readonly sortable?: boolean;
@@ -290,6 +302,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
290
302
  readonly description?: string;
291
303
  readonly maxLength?: number;
292
304
  readonly minLength?: number;
305
+ readonly autoComplete?: string;
293
306
  readonly required?: boolean;
294
307
  readonly searchable?: boolean;
295
308
  readonly sortable?: boolean;
@@ -312,6 +325,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
312
325
  readonly description?: string;
313
326
  readonly maxLength?: number;
314
327
  readonly minLength?: number;
328
+ readonly autoComplete?: string;
315
329
  readonly required?: boolean;
316
330
  readonly searchable?: boolean;
317
331
  readonly sortable?: boolean;
@@ -334,6 +348,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
334
348
  readonly description?: string;
335
349
  readonly maxLength?: number;
336
350
  readonly minLength?: number;
351
+ readonly autoComplete?: string;
337
352
  readonly required?: boolean;
338
353
  readonly searchable?: boolean;
339
354
  readonly sortable?: boolean;
@@ -356,6 +371,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
356
371
  readonly description?: string;
357
372
  readonly maxLength?: number;
358
373
  readonly minLength?: number;
374
+ readonly autoComplete?: string;
359
375
  readonly required?: boolean;
360
376
  readonly searchable?: boolean;
361
377
  readonly sortable?: boolean;
@@ -393,6 +409,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
393
409
  readonly description?: string;
394
410
  readonly maxLength?: number;
395
411
  readonly minLength?: number;
412
+ readonly autoComplete?: string;
396
413
  readonly required?: boolean;
397
414
  readonly searchable?: boolean;
398
415
  readonly sortable?: boolean;
@@ -415,6 +432,7 @@ export declare const inboundMessageEntity: import("@cosmicdrift/kumiko-types/fie
415
432
  readonly description?: string;
416
433
  readonly maxLength?: number;
417
434
  readonly minLength?: number;
435
+ readonly autoComplete?: string;
418
436
  readonly required?: boolean;
419
437
  readonly searchable?: boolean;
420
438
  readonly sortable?: boolean;
@@ -441,6 +459,7 @@ export declare const mailThreadEntity: import("@cosmicdrift/kumiko-types/fields"
441
459
  readonly description?: string;
442
460
  readonly maxLength?: number;
443
461
  readonly minLength?: number;
462
+ readonly autoComplete?: string;
444
463
  readonly required?: boolean;
445
464
  readonly searchable?: boolean;
446
465
  readonly sortable?: boolean;
@@ -463,6 +482,7 @@ export declare const mailThreadEntity: import("@cosmicdrift/kumiko-types/fields"
463
482
  readonly description?: string;
464
483
  readonly maxLength?: number;
465
484
  readonly minLength?: number;
485
+ readonly autoComplete?: string;
466
486
  readonly required?: boolean;
467
487
  readonly searchable?: boolean;
468
488
  readonly sortable?: boolean;
@@ -528,6 +548,7 @@ export declare const syncCursorEntity: import("@cosmicdrift/kumiko-types/fields"
528
548
  readonly description?: string;
529
549
  readonly maxLength?: number;
530
550
  readonly minLength?: number;
551
+ readonly autoComplete?: string;
531
552
  readonly required?: boolean;
532
553
  readonly searchable?: boolean;
533
554
  readonly sortable?: boolean;
@@ -550,6 +571,7 @@ export declare const syncCursorEntity: import("@cosmicdrift/kumiko-types/fields"
550
571
  readonly description?: string;
551
572
  readonly maxLength?: number;
552
573
  readonly minLength?: number;
574
+ readonly autoComplete?: string;
553
575
  readonly required?: boolean;
554
576
  readonly searchable?: boolean;
555
577
  readonly sortable?: boolean;
@@ -572,6 +594,7 @@ export declare const syncCursorEntity: import("@cosmicdrift/kumiko-types/fields"
572
594
  readonly description?: string;
573
595
  readonly maxLength?: number;
574
596
  readonly minLength?: number;
597
+ readonly autoComplete?: string;
575
598
  readonly required?: boolean;
576
599
  readonly searchable?: boolean;
577
600
  readonly sortable?: boolean;
@@ -615,6 +638,7 @@ export declare const seenMessageEntity: import("@cosmicdrift/kumiko-types/fields
615
638
  readonly description?: string;
616
639
  readonly maxLength?: number;
617
640
  readonly minLength?: number;
641
+ readonly autoComplete?: string;
618
642
  readonly required?: boolean;
619
643
  readonly searchable?: boolean;
620
644
  readonly sortable?: boolean;
@@ -637,6 +661,7 @@ export declare const seenMessageEntity: import("@cosmicdrift/kumiko-types/fields
637
661
  readonly description?: string;
638
662
  readonly maxLength?: number;
639
663
  readonly minLength?: number;
664
+ readonly autoComplete?: string;
640
665
  readonly required?: boolean;
641
666
  readonly searchable?: boolean;
642
667
  readonly sortable?: boolean;