@vxil/feature-configs 0.1.1 → 0.3.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.
- package/dist/index.d.ts +145 -35
- package/dist/index.js +542 -45
- package/package.json +1 -1
- package/src/index.test.ts +544 -28
- package/src/index.ts +650 -102
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,49 @@
|
|
|
1
1
|
import { type Static, type TSchema } from '@sinclair/typebox';
|
|
2
2
|
export * from './hooks.js';
|
|
3
3
|
export * from './readmodels.js';
|
|
4
|
+
export declare const RESERVED_CREDIT_TYPES: ReadonlySet<string>;
|
|
5
|
+
/** True when a credit_type is a vxil-COGS reserved type (grant/consume/config
|
|
6
|
+
* of which is restricted to internal platform machinery). */
|
|
7
|
+
export declare function isReservedCreditType(creditType: string): boolean;
|
|
8
|
+
export declare const NOTIFICATION_TEMPLATE_PLACEHOLDERS: Readonly<Record<string, readonly string[]>>;
|
|
9
|
+
/** Per-override caps (D4). Bodies are emails, not documents. */
|
|
10
|
+
export declare const NOTIF_OVERRIDE_SUBJECT_MAX = 500;
|
|
11
|
+
export declare const NOTIF_OVERRIDE_BODY_MAX = 20000;
|
|
12
|
+
/** Whole-map caps: keeps one manifest (and the KV row every send reads) small. */
|
|
13
|
+
export declare const NOTIF_OVERRIDE_MAX_LOCALES_PER_TEMPLATE = 20;
|
|
14
|
+
export declare const NOTIF_OVERRIDE_MAX_BYTES: number;
|
|
15
|
+
/**
|
|
16
|
+
* D4 — validate `templates.overrides` at CONFIG-WRITE time. Returns [] when the
|
|
17
|
+
* bag is absent or clean. Every rule fails LOUD rather than shipping something
|
|
18
|
+
* that silently renders wrong in a customer's inbox:
|
|
19
|
+
* • overrides present with `allowOverride:false` → rejected (never inert);
|
|
20
|
+
* • an unknown template id / locale tag → rejected;
|
|
21
|
+
* • an unknown `{{placeholder}}` in subject/html/text → rejected (the class of
|
|
22
|
+
* typo that renders as an empty string in a live email);
|
|
23
|
+
* • size caps (per-locale count, whole-map bytes) → rejected.
|
|
24
|
+
* Pure, so it is unit-tested without a control plane.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateNotificationOverrides(templates: {
|
|
27
|
+
allowOverride?: boolean;
|
|
28
|
+
overrides?: Record<string, Record<string, {
|
|
29
|
+
subject?: string;
|
|
30
|
+
html?: string;
|
|
31
|
+
text?: string;
|
|
32
|
+
}>>;
|
|
33
|
+
} | undefined): string[];
|
|
4
34
|
export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
5
35
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
6
36
|
fromEmail: import("@sinclair/typebox").TString;
|
|
7
37
|
fromName: import("@sinclair/typebox").TString;
|
|
8
38
|
replyTo: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
39
|
resendApiKeyRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
40
|
+
webhookSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
10
41
|
provider: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resend">, import("@sinclair/typebox").TLiteral<"mock">]>;
|
|
11
42
|
defaultLocale: import("@sinclair/typebox").TString;
|
|
12
|
-
retry: import("@sinclair/typebox").TObject<{
|
|
43
|
+
retry: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
13
44
|
maxAttempts: import("@sinclair/typebox").TInteger;
|
|
14
45
|
backoff: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"exponential">, import("@sinclair/typebox").TLiteral<"linear">]>;
|
|
15
|
-
}
|
|
46
|
+
}>>;
|
|
16
47
|
suppression: import("@sinclair/typebox").TObject<{
|
|
17
48
|
softBounceThreshold: import("@sinclair/typebox").TInteger;
|
|
18
49
|
}>;
|
|
@@ -20,13 +51,41 @@ export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObj
|
|
|
20
51
|
perDay: import("@sinclair/typebox").TInteger;
|
|
21
52
|
perTenantSec: import("@sinclair/typebox").TInteger;
|
|
22
53
|
}>;
|
|
23
|
-
templates: import("@sinclair/typebox").TObject<{
|
|
54
|
+
templates: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
24
55
|
allowOverride: import("@sinclair/typebox").TBoolean;
|
|
25
|
-
|
|
56
|
+
overrides: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
|
|
57
|
+
subject: import("@sinclair/typebox").TString;
|
|
58
|
+
html: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
59
|
+
text: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
60
|
+
}>>>>;
|
|
61
|
+
}>>;
|
|
26
62
|
/** in-app inbox channel (send with channel: 'inbox' | 'both') */
|
|
27
63
|
inboxEnabled: import("@sinclair/typebox").TBoolean;
|
|
64
|
+
/** §11b.5 broadcast campaigns channel. Optional bag (= 1 leaf): absent means
|
|
65
|
+
* disabled; per-campaign quiet_hours / freq_cap overrides live on the
|
|
66
|
+
* notifications.campaigns ROW (tenant data), not here. Folded into the
|
|
67
|
+
* canonical schema 2026-07-18 (M21/#4 — Value.Clean previously STRIPPED the
|
|
68
|
+
* worker-local extension, so campaigns 403'd via the real config path). */
|
|
69
|
+
broadcast: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
70
|
+
enabled: import("@sinclair/typebox").TBoolean;
|
|
71
|
+
/** tenant-default per-recipient quiet window (defer-not-drop); a
|
|
72
|
+
* per-campaign quiet_hours wins over it. Mirrors the campaigns-row shape
|
|
73
|
+
* (workers/notifications-v1 CampaignBody.quiet_hours). start/end are
|
|
74
|
+
* pattern-pinned to what the worker's parseHhMm actually parses — a
|
|
75
|
+
* looser string ('10pm') would validate but FAIL OPEN at runtime
|
|
76
|
+
* (quiet window silently ignored). */
|
|
77
|
+
defaultQuietHours: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
78
|
+
tz: import("@sinclair/typebox").TString;
|
|
79
|
+
start: import("@sinclair/typebox").TString;
|
|
80
|
+
end: import("@sinclair/typebox").TString;
|
|
81
|
+
}>>;
|
|
82
|
+
/** default rolling per-user-per-day campaign-send cap across campaigns */
|
|
83
|
+
freqCapPerUserPerDay: import("@sinclair/typebox").TInteger;
|
|
84
|
+
}>>;
|
|
28
85
|
}>;
|
|
29
86
|
export type NotificationsConfig = Static<typeof NotificationsConfigSchema>;
|
|
87
|
+
/** The §11b.5 broadcast bag as persisted (present ⇒ leaf defaults applied). */
|
|
88
|
+
export type BroadcastConfig = NonNullable<NotificationsConfig['broadcast']>;
|
|
30
89
|
export declare const JobsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
31
90
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
32
91
|
retry: import("@sinclair/typebox").TObject<{
|
|
@@ -72,16 +131,29 @@ export declare const JobsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
72
131
|
}>;
|
|
73
132
|
}>;
|
|
74
133
|
export type JobsConfig = Static<typeof JobsConfigSchema>;
|
|
134
|
+
declare const OidcProviderSchema: import("@sinclair/typebox").TObject<{
|
|
135
|
+
issuer: import("@sinclair/typebox").TString;
|
|
136
|
+
clientId: import("@sinclair/typebox").TString;
|
|
137
|
+
clientSecretRef: import("@sinclair/typebox").TString;
|
|
138
|
+
scopes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
139
|
+
claims: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
140
|
+
email: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
141
|
+
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
142
|
+
roles: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
143
|
+
}>>;
|
|
144
|
+
allowedDomains: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
145
|
+
autoLink: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
146
|
+
}>;
|
|
75
147
|
export declare const AuthConfigSchema: import("@sinclair/typebox").TObject<{
|
|
76
148
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
77
|
-
methods: import("@sinclair/typebox").TObject<{
|
|
149
|
+
methods: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
78
150
|
emailPassword: import("@sinclair/typebox").TBoolean;
|
|
79
151
|
magicLink: import("@sinclair/typebox").TBoolean;
|
|
80
152
|
google: import("@sinclair/typebox").TBoolean;
|
|
81
153
|
github: import("@sinclair/typebox").TBoolean;
|
|
82
154
|
apple: import("@sinclair/typebox").TBoolean;
|
|
83
155
|
facebook: import("@sinclair/typebox").TBoolean;
|
|
84
|
-
}
|
|
156
|
+
}>>;
|
|
85
157
|
providers: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
86
158
|
google: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
87
159
|
clientIdRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -105,10 +177,24 @@ export declare const AuthConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
105
177
|
clientSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
106
178
|
audRefs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
107
179
|
}>>;
|
|
180
|
+
oidc: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
181
|
+
issuer: import("@sinclair/typebox").TString;
|
|
182
|
+
clientId: import("@sinclair/typebox").TString;
|
|
183
|
+
clientSecretRef: import("@sinclair/typebox").TString;
|
|
184
|
+
scopes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
185
|
+
claims: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
186
|
+
email: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
187
|
+
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
188
|
+
roles: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
189
|
+
}>>;
|
|
190
|
+
allowedDomains: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
191
|
+
autoLink: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
192
|
+
}>>;
|
|
108
193
|
}>>;
|
|
109
194
|
session: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
110
195
|
ttlMinutes: import("@sinclair/typebox").TInteger;
|
|
111
196
|
refreshTtlDays: import("@sinclair/typebox").TInteger;
|
|
197
|
+
maxConcurrent: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
112
198
|
}>>;
|
|
113
199
|
password: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
114
200
|
minLength: import("@sinclair/typebox").TInteger;
|
|
@@ -125,6 +211,7 @@ export declare const AuthConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
125
211
|
codeTtlMinutes: import("@sinclair/typebox").TInteger;
|
|
126
212
|
maxAttempts: import("@sinclair/typebox").TInteger;
|
|
127
213
|
resendCooldownSec: import("@sinclair/typebox").TInteger;
|
|
214
|
+
testRecipients: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
128
215
|
}>>;
|
|
129
216
|
anonymous: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
130
217
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
@@ -132,7 +219,21 @@ export declare const AuthConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
132
219
|
orgClaims: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
133
220
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
134
221
|
}>>;
|
|
222
|
+
security: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
223
|
+
lockout: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
224
|
+
maxFailures: import("@sinclair/typebox").TInteger;
|
|
225
|
+
windowMinutes: import("@sinclair/typebox").TInteger;
|
|
226
|
+
lockMinutes: import("@sinclair/typebox").TInteger;
|
|
227
|
+
}>>;
|
|
228
|
+
breachedPasswords: import("@sinclair/typebox").TBoolean;
|
|
229
|
+
captchaSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
230
|
+
allowedRedirectOrigins: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
231
|
+
}>>;
|
|
135
232
|
}>;
|
|
233
|
+
/** The security bag as persisted (present ⇒ leaf defaults applied). */
|
|
234
|
+
export type AuthSecurityConfig = NonNullable<Static<typeof AuthConfigSchema>['security']>;
|
|
235
|
+
/** The RB-2 generic OIDC / SSO issuer block (`providers.oidc`). */
|
|
236
|
+
export type AuthOidcConfig = Static<typeof OidcProviderSchema>;
|
|
136
237
|
export type AuthConfig = Static<typeof AuthConfigSchema>;
|
|
137
238
|
export declare const RateLimitsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
138
239
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
@@ -144,7 +245,6 @@ export declare const RateLimitsConfigSchema: import("@sinclair/typebox").TObject
|
|
|
144
245
|
export type RateLimitsConfig = Static<typeof RateLimitsConfigSchema>;
|
|
145
246
|
export declare const FilesConfigSchema: import("@sinclair/typebox").TObject<{
|
|
146
247
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
147
|
-
bucketRef: import("@sinclair/typebox").TString;
|
|
148
248
|
uploadUrlTtl: import("@sinclair/typebox").TInteger;
|
|
149
249
|
downloadUrlTtl: import("@sinclair/typebox").TInteger;
|
|
150
250
|
quotas: import("@sinclair/typebox").TObject<{
|
|
@@ -153,10 +253,6 @@ export declare const FilesConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
153
253
|
maxObjectCount: import("@sinclair/typebox").TInteger;
|
|
154
254
|
}>;
|
|
155
255
|
allowedContentTypes: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
156
|
-
contentScan: import("@sinclair/typebox").TObject<{
|
|
157
|
-
enabled: import("@sinclair/typebox").TBoolean;
|
|
158
|
-
quarantineOnFail: import("@sinclair/typebox").TBoolean;
|
|
159
|
-
}>;
|
|
160
256
|
sharedLinks: import("@sinclair/typebox").TObject<{
|
|
161
257
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
162
258
|
maxTtl: import("@sinclair/typebox").TInteger;
|
|
@@ -240,9 +336,6 @@ export declare const McpConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
240
336
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
241
337
|
exposureLevel: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"all">, import("@sinclair/typebox").TLiteral<"read-only">, import("@sinclair/typebox").TLiteral<"custom">]>;
|
|
242
338
|
allowToolList: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
243
|
-
scopedKey: import("@sinclair/typebox").TObject<{
|
|
244
|
-
perAgentKeys: import("@sinclair/typebox").TBoolean;
|
|
245
|
-
}>;
|
|
246
339
|
rateLimits: import("@sinclair/typebox").TObject<{
|
|
247
340
|
toolCallsPerMin: import("@sinclair/typebox").TInteger;
|
|
248
341
|
}>;
|
|
@@ -300,9 +393,6 @@ export declare const ActivityFeedConfigSchema: import("@sinclair/typebox").TObje
|
|
|
300
393
|
copyLimit: import("@sinclair/typebox").TInteger;
|
|
301
394
|
maxFollowing: import("@sinclair/typebox").TInteger;
|
|
302
395
|
}>;
|
|
303
|
-
aggregation: import("@sinclair/typebox").TObject<{
|
|
304
|
-
maxGroupActivities: import("@sinclair/typebox").TInteger;
|
|
305
|
-
}>;
|
|
306
396
|
realtime: import("@sinclair/typebox").TObject<{
|
|
307
397
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
308
398
|
}>;
|
|
@@ -310,9 +400,6 @@ export declare const ActivityFeedConfigSchema: import("@sinclair/typebox").TObje
|
|
|
310
400
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
311
401
|
digestCadence: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"off">, import("@sinclair/typebox").TLiteral<"hourly">, import("@sinclair/typebox").TLiteral<"daily">]>;
|
|
312
402
|
}>;
|
|
313
|
-
rateLimit: import("@sinclair/typebox").TObject<{
|
|
314
|
-
addPerSec: import("@sinclair/typebox").TInteger;
|
|
315
|
-
}>;
|
|
316
403
|
}>;
|
|
317
404
|
export type ActivityFeedConfig = Static<typeof ActivityFeedConfigSchema>;
|
|
318
405
|
export declare const VectorSearchConfigSchema: import("@sinclair/typebox").TObject<{
|
|
@@ -430,6 +517,7 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
430
517
|
publicSdkKey: import("@sinclair/typebox").TString;
|
|
431
518
|
secretApiKeyRef: import("@sinclair/typebox").TString;
|
|
432
519
|
webhookSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
520
|
+
acceptSandbox: import("@sinclair/typebox").TBoolean;
|
|
433
521
|
}>>;
|
|
434
522
|
paypal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
435
523
|
clientIdRef: import("@sinclair/typebox").TString;
|
|
@@ -438,9 +526,6 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
438
526
|
sandbox: import("@sinclair/typebox").TBoolean;
|
|
439
527
|
}>>;
|
|
440
528
|
returnUrl: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
441
|
-
prices: import("@sinclair/typebox").TObject<{
|
|
442
|
-
catalogRef: import("@sinclair/typebox").TString;
|
|
443
|
-
}>;
|
|
444
529
|
defaults: import("@sinclair/typebox").TObject<{
|
|
445
530
|
currency: import("@sinclair/typebox").TString;
|
|
446
531
|
trialDays: import("@sinclair/typebox").TInteger;
|
|
@@ -463,19 +548,19 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
463
548
|
}>>;
|
|
464
549
|
priceMap: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TString>>;
|
|
465
550
|
autoRefundOnJobFailure: import("@sinclair/typebox").TBoolean;
|
|
551
|
+
grace: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
552
|
+
pastDueDays: import("@sinclair/typebox").TInteger;
|
|
553
|
+
}>>;
|
|
554
|
+
enforcePeriodEnd: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
555
|
+
slackHours: import("@sinclair/typebox").TInteger;
|
|
556
|
+
}>>;
|
|
466
557
|
}>>;
|
|
467
|
-
webhooks: import("@sinclair/typebox").TObject<{
|
|
468
|
-
forwardToTenantUrl: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
469
|
-
}>;
|
|
470
558
|
}>;
|
|
471
559
|
export type PaymentsConfig = Static<typeof PaymentsConfigSchema>;
|
|
472
560
|
export declare const FunctionsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
473
561
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
474
|
-
runtime: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"isolate">, import("@sinclair/typebox").TLiteral<"container">]>;
|
|
475
562
|
defaultLimits: import("@sinclair/typebox").TObject<{
|
|
476
563
|
cpuMs: import("@sinclair/typebox").TInteger;
|
|
477
|
-
timeoutMs: import("@sinclair/typebox").TInteger;
|
|
478
|
-
memoryMb: import("@sinclair/typebox").TInteger;
|
|
479
564
|
}>;
|
|
480
565
|
metering: import("@sinclair/typebox").TObject<{
|
|
481
566
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
@@ -539,14 +624,8 @@ export declare const CopilotConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
539
624
|
guestToolAllow: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
540
625
|
}>>;
|
|
541
626
|
}>>;
|
|
542
|
-
escalation: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
543
|
-
enabled: import("@sinclair/typebox").TBoolean;
|
|
544
|
-
handler: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"comments">, import("@sinclair/typebox").TLiteral<"notifications">]>;
|
|
545
|
-
notifyTemplate: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
546
|
-
}>>;
|
|
547
627
|
limits: import("@sinclair/typebox").TObject<{
|
|
548
628
|
consumeCredits: import("@sinclair/typebox").TBoolean;
|
|
549
|
-
tokensPerUserPerDay: import("@sinclair/typebox").TInteger;
|
|
550
629
|
}>;
|
|
551
630
|
widget: import("@sinclair/typebox").TObject<{
|
|
552
631
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
@@ -562,6 +641,21 @@ export declare const CONFIG_FLAG_CAP = 15;
|
|
|
562
641
|
* Per features/auth.md §4: an OPTIONAL object (e.g. a provider credential
|
|
563
642
|
* block) counts as ONE flag — the tenant's decision is "configure it or
|
|
564
643
|
* not", not each inner ref. */
|
|
644
|
+
/** The auth lifecycle events an `authHook` binding may name (F4-30) — the
|
|
645
|
+
* closed union `packages/config` types as AuthHookEvent; the control-plane
|
|
646
|
+
* reconciler maps each to its `auth.<event>` audit-event prefix. */
|
|
647
|
+
export declare const AUTH_HOOK_EVENTS: readonly ["user.created", "session.created", "session.revoked", "signin.failure"];
|
|
648
|
+
export type AuthHookEvent = (typeof AUTH_HOOK_EVENTS)[number];
|
|
649
|
+
/** F4-29 test-recipient entry grammar (shared by the validator and auth-v1's
|
|
650
|
+
* matcher): an exact email, a `*@domain` glob, or a +E.164 phone number. */
|
|
651
|
+
export declare const TEST_RECIPIENT_EMAIL_RE: RegExp;
|
|
652
|
+
export declare const TEST_RECIPIENT_GLOB_RE: RegExp;
|
|
653
|
+
export declare const TEST_RECIPIENT_E164_RE: RegExp;
|
|
654
|
+
export declare function isTestRecipientPattern(entry: string): boolean;
|
|
655
|
+
/** True iff `identifier` (an email today) matches one configured entry:
|
|
656
|
+
* exact (case-insensitive) or the `*@domain` glob. +E.164 entries never match
|
|
657
|
+
* an email. */
|
|
658
|
+
export declare function matchesTestRecipient(identifier: string, entries: readonly string[] | undefined): boolean;
|
|
565
659
|
export declare function countLeaves(schema: TSchema): number;
|
|
566
660
|
export interface ConfigValidation {
|
|
567
661
|
ok: boolean;
|
|
@@ -585,3 +679,19 @@ export declare const MCP_MAX_PROMPTS = 32;
|
|
|
585
679
|
* validation below and the control-plane deploy clamp. */
|
|
586
680
|
export declare const DENY_FUNCTION_SCOPES: Set<string>;
|
|
587
681
|
export declare function validateFeatureConfig(feature: string, raw: unknown): ConfigValidation;
|
|
682
|
+
export declare const FEATURE_KEYS: readonly ["notifications", "jobs", "auth", "rate-limits", "files", "webhooks", "comments", "cms", "mcp", "realtime", "presence", "orgs", "activity-feed", "vector-search", "ai", "rag", "payments", "functions", "copilot"];
|
|
683
|
+
export type FeatureKey = (typeof FEATURE_KEYS)[number];
|
|
684
|
+
/** The hand-authored "when to use" intent a machine schema cannot convey.
|
|
685
|
+
* REQUIRED for every feature (Record key-closure): a feature added to
|
|
686
|
+
* FEATURE_KEYS without a hint is a compile error naming the missing key. */
|
|
687
|
+
export interface PlannerHint {
|
|
688
|
+
/** One or two sentences: when an app needs this feature. */
|
|
689
|
+
whenToUse: string;
|
|
690
|
+
/** Soft priors — words/needs that suggest the feature (NOT a matcher). */
|
|
691
|
+
signals: string[];
|
|
692
|
+
/** When NOT to pick it (disambiguation vs neighbors). */
|
|
693
|
+
notFor: string;
|
|
694
|
+
/** Features that must be enabled alongside (runtime substrate deps). */
|
|
695
|
+
dependsOn: FeatureKey[];
|
|
696
|
+
}
|
|
697
|
+
export declare const FEATURE_HINTS: Record<FeatureKey, PlannerHint>;
|