@digilogiclabs/platform-core 1.7.0 → 1.9.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.
@@ -1,91 +1,268 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  /**
4
- * Security Utilities
4
+ * Beta Access Management Interface
5
5
  *
6
- * HTML escaping, input detection, sanitization helpers,
7
- * timing-safe comparison, error sanitization, and request
8
- * correlation for safe, consistent security across all apps.
9
- */
10
- /** Regex for protocol-prefixed URLs */
11
- declare const URL_PROTOCOL_PATTERN: RegExp;
12
- /** Regex for bare domain names with common TLDs */
13
- declare const URL_DOMAIN_PATTERN: RegExp;
14
- /** Regex for HTML tags */
15
- declare const HTML_TAG_PATTERN: RegExp;
16
- /**
17
- * Escape HTML special characters to prevent injection.
18
- * Use when inserting user content into HTML email templates or rendered HTML.
19
- */
20
- declare function escapeHtml(str: string): string;
21
- /** Check if a string contains protocol-prefixed URLs or bare domains */
22
- declare function containsUrls(str: string): boolean;
23
- /** Check if a string contains HTML tags */
24
- declare function containsHtml(str: string): boolean;
25
- /** Strip all HTML tags from a string */
26
- declare function stripHtml(str: string): string;
27
- /**
28
- * Defang URLs to prevent auto-linking in email clients.
29
- * Converts https://evil.com → hxxps://evil[.]com
30
- */
31
- declare function defangUrl(str: string): string;
32
- /**
33
- * Sanitize user content for safe insertion into HTML email templates.
34
- * Escapes HTML entities AND defangs any URLs that slipped through validation.
35
- */
36
- declare function sanitizeForEmail(str: string): string;
37
- /**
38
- * Constant-time string comparison to prevent timing side-channel attacks.
39
- * Use for comparing secrets, tokens, API keys, HMAC signatures, etc.
6
+ * Provides a vendor-agnostic way to manage beta/early-access programs.
7
+ * Handles invite codes, access gating, settings, and analytics across
8
+ * all DLL Platform applications.
40
9
  *
41
- * Returns false (not throws) for length mismatches — still constant-time
42
- * relative to the shorter string to avoid leaking length info.
10
+ * Features:
11
+ * - Beta mode settings (mode, require code, custom message)
12
+ * - Invite code management (create, validate, consume, revoke)
13
+ * - Multi-use codes with usage tracking and expiration
14
+ * - Profile tagging (beta tester flag, join date)
15
+ * - Analytics (usage stats, per-code reports)
16
+ * - Live toggling (closed beta → open beta → public launch)
43
17
  *
44
18
  * @example
45
19
  * ```typescript
46
- * if (!constantTimeEqual(providedToken, expectedSecret)) {
47
- * return { status: 401, error: 'Invalid token' }
48
- * }
49
- * ```
50
- */
51
- declare function constantTimeEqual(a: string, b: string): boolean;
52
- /**
53
- * Sanitize an error for client-facing API responses.
20
+ * import { MemoryBeta } from '@digilogiclabs/platform-core';
54
21
  *
55
- * - 4xx errors: returns the actual message (client needs to know what went wrong)
56
- * - 5xx errors: returns a generic message (never leak internals to clients)
57
- * - Development mode: optionally includes stack trace for debugging
22
+ * const beta = new MemoryBeta();
58
23
  *
59
- * @example
60
- * ```typescript
61
- * catch (error) {
62
- * const { message, code } = sanitizeApiError(error, 500)
63
- * return Response.json({ error: message, code }, { status: 500 })
24
+ * // Check if beta is active
25
+ * const settings = await beta.getSettings();
26
+ * if (settings.requireInviteCode) {
27
+ * const result = await beta.validateCode('BETA2026');
28
+ * if (result.valid) {
29
+ * await beta.consumeCode('BETA2026', 'user_123');
30
+ * }
64
31
  * }
65
- * ```
66
- */
67
- declare function sanitizeApiError(error: unknown, statusCode: number, isDevelopment?: boolean): {
68
- message: string;
69
- code?: string;
70
- stack?: string;
71
- };
72
- /**
73
- * Extract a correlation/request ID from standard headers, or generate one.
74
32
  *
75
- * Checks (in order): X-Request-ID, X-Correlation-ID, then falls back to
76
- * crypto.randomUUID(). Works with any headers-like object (plain object,
77
- * Headers API, or a getter function).
33
+ * // Create invite codes
34
+ * const codes = await beta.createCodes({
35
+ * count: 10,
36
+ * prefix: 'DLL',
37
+ * maxUses: 5,
38
+ * createdBy: 'admin',
39
+ * });
78
40
  *
79
- * @example
80
- * ```typescript
81
- * // With Next.js request
82
- * const id = getCorrelationId((name) => request.headers.get(name))
83
- *
84
- * // With plain object
85
- * const id = getCorrelationId({ 'x-request-id': 'abc-123' })
41
+ * // Transition to public launch
42
+ * await beta.updateSettings({ betaMode: false, requireInviteCode: false });
86
43
  * ```
87
44
  */
88
- declare function getCorrelationId(headers: Record<string, string | string[] | undefined> | ((name: string) => string | null | undefined)): string;
45
+ /** Beta program settings */
46
+ interface BetaSettings {
47
+ /** Whether the app is in beta mode (shows beta messaging) */
48
+ betaMode: boolean;
49
+ /** Whether an invite code is required to sign up */
50
+ requireInviteCode: boolean;
51
+ /** Custom message to display during beta */
52
+ betaMessage: string;
53
+ }
54
+ /** Options for updating beta settings */
55
+ interface UpdateBetaSettingsOptions {
56
+ betaMode?: boolean;
57
+ requireInviteCode?: boolean;
58
+ betaMessage?: string;
59
+ updatedBy?: string;
60
+ }
61
+ /** A beta invite code */
62
+ interface BetaInviteCode {
63
+ /** Unique identifier */
64
+ id: string;
65
+ /** The invite code string (normalized to uppercase) */
66
+ code: string;
67
+ /** Maximum number of times this code can be used */
68
+ maxUses: number;
69
+ /** Current number of times this code has been used */
70
+ currentUses: number;
71
+ /** Optional expiration date */
72
+ expiresAt: Date | null;
73
+ /** Who created this code */
74
+ createdBy: string;
75
+ /** Admin notes about this code */
76
+ notes: string;
77
+ /** Whether this code is active (soft delete) */
78
+ isActive: boolean;
79
+ /** When this code was created */
80
+ createdAt: Date;
81
+ }
82
+ /** Options for creating invite codes */
83
+ interface CreateBetaCodesOptions {
84
+ /** Number of codes to generate (max 50) */
85
+ count?: number;
86
+ /** Prefix for generated codes (e.g., 'DLL' → 'DLL-A1B2C3D4') */
87
+ prefix?: string;
88
+ /** Specific code string (for named codes like 'BETA2026') */
89
+ code?: string;
90
+ /** Maximum uses per code (default: 1) */
91
+ maxUses?: number;
92
+ /** Optional expiration date */
93
+ expiresAt?: Date;
94
+ /** Who is creating the codes */
95
+ createdBy: string;
96
+ /** Admin notes */
97
+ notes?: string;
98
+ }
99
+ /** Filter for listing invite codes */
100
+ type BetaCodeStatus = "unused" | "partial" | "exhausted" | "expired" | "revoked";
101
+ interface ListBetaCodesOptions {
102
+ /** Filter by status */
103
+ status?: BetaCodeStatus;
104
+ /** Filter by active state */
105
+ isActive?: boolean;
106
+ /** Pagination offset */
107
+ offset?: number;
108
+ /** Pagination limit */
109
+ limit?: number;
110
+ }
111
+ /** Result of validating a beta code (read-only, does not consume) */
112
+ interface BetaValidationResult {
113
+ /** Whether the code is valid */
114
+ valid: boolean;
115
+ /** Human-readable message */
116
+ message: string;
117
+ /** The normalized code (if valid) */
118
+ code?: string;
119
+ /** Remaining uses (if valid) */
120
+ remainingUses?: number;
121
+ }
122
+ /** Result of consuming a beta code */
123
+ interface BetaConsumeResult {
124
+ /** Whether the code was successfully consumed */
125
+ success: boolean;
126
+ /** Human-readable message */
127
+ message: string;
128
+ }
129
+ /** Beta tester profile metadata */
130
+ interface BetaTester {
131
+ /** User identifier */
132
+ userId: string;
133
+ /** The invite code they used */
134
+ inviteCode: string;
135
+ /** Whether they are flagged as a beta tester */
136
+ isBetaTester: boolean;
137
+ /** When they joined beta */
138
+ betaJoinedAt: Date;
139
+ }
140
+ /** Aggregate beta program statistics */
141
+ interface BetaStats {
142
+ /** Total number of beta testers */
143
+ totalBetaTesters: number;
144
+ /** Total invite codes created */
145
+ totalCodes: number;
146
+ /** Number of active (usable) codes */
147
+ activeCodes: number;
148
+ /** Total uses across all codes */
149
+ totalUses: number;
150
+ /** Total remaining capacity across all codes */
151
+ totalRemaining: number;
152
+ /** Earliest beta signup */
153
+ firstBetaSignup: Date | null;
154
+ /** Most recent beta signup */
155
+ latestBetaSignup: Date | null;
156
+ }
157
+ /** Per-code usage report */
158
+ interface BetaCodeUsageReport {
159
+ /** The invite code */
160
+ code: string;
161
+ /** Admin notes */
162
+ notes: string;
163
+ /** Maximum uses */
164
+ maxUses: number;
165
+ /** Current uses */
166
+ currentUses: number;
167
+ /** Remaining uses */
168
+ remainingUses: number;
169
+ /** Usage percentage (0-100) */
170
+ usagePercent: number;
171
+ /** Whether the code is active */
172
+ isActive: boolean;
173
+ /** Expiration date */
174
+ expiresAt: Date | null;
175
+ /** Creation date */
176
+ createdAt: Date;
177
+ }
178
+ /** Configuration for beta adapters */
179
+ interface BetaConfig {
180
+ /** Default beta mode on initialization */
181
+ defaultBetaMode?: boolean;
182
+ /** Default require invite code on initialization */
183
+ defaultRequireInviteCode?: boolean;
184
+ /** Default beta message */
185
+ defaultBetaMessage?: string;
186
+ /** Code prefix for generated codes (e.g., 'DLL', 'WIAN') */
187
+ codePrefix?: string;
188
+ /** Maximum codes per createCodes call (default: 50) */
189
+ maxCodesPerBatch?: number;
190
+ }
191
+ interface IBeta {
192
+ /** Get current beta program settings */
193
+ getSettings(): Promise<BetaSettings>;
194
+ /** Update beta program settings (live toggle, no redeploy needed) */
195
+ updateSettings(options: UpdateBetaSettingsOptions): Promise<void>;
196
+ /** Create one or more invite codes */
197
+ createCodes(options: CreateBetaCodesOptions): Promise<BetaInviteCode[]>;
198
+ /** List invite codes with optional filtering */
199
+ listCodes(options?: ListBetaCodesOptions): Promise<BetaInviteCode[]>;
200
+ /** Get a specific invite code by its code string */
201
+ getCode(code: string): Promise<BetaInviteCode | null>;
202
+ /** Revoke an invite code (soft delete — sets isActive to false) */
203
+ revokeCode(code: string): Promise<void>;
204
+ /**
205
+ * Validate an invite code (read-only, does not consume).
206
+ * If requireInviteCode is false, always returns { valid: true }.
207
+ */
208
+ validateCode(code: string): Promise<BetaValidationResult>;
209
+ /**
210
+ * Consume an invite code for a user (increments usage, tags user).
211
+ * Should be called after successful signup, not before.
212
+ */
213
+ consumeCode(code: string, userId: string): Promise<BetaConsumeResult>;
214
+ /** Check if a user is a beta tester */
215
+ isBetaTester(userId: string): Promise<boolean>;
216
+ /** Get beta tester details for a user */
217
+ getBetaTester(userId: string): Promise<BetaTester | null>;
218
+ /** List all beta testers */
219
+ listBetaTesters(options?: {
220
+ offset?: number;
221
+ limit?: number;
222
+ }): Promise<BetaTester[]>;
223
+ /** Get aggregate beta program statistics */
224
+ getStats(): Promise<BetaStats>;
225
+ /** Get per-code usage reports */
226
+ getCodeUsageReports(): Promise<BetaCodeUsageReport[]>;
227
+ /** Check beta service health */
228
+ healthCheck(): Promise<boolean>;
229
+ }
230
+ /** Generate a random hex code with prefix (e.g., 'DLL-A1B2C3D4') */
231
+ declare function generateBetaCode(prefix?: string): string;
232
+ /** Normalize a code for comparison (trim + uppercase) */
233
+ declare function normalizeBetaCode(code: string): string;
234
+ /** Generate a unique ID for beta records */
235
+ declare function generateBetaId(): string;
236
+ declare class MemoryBeta implements IBeta {
237
+ private settings;
238
+ private codes;
239
+ private testers;
240
+ private config;
241
+ constructor(config?: BetaConfig);
242
+ getSettings(): Promise<BetaSettings>;
243
+ updateSettings(options: UpdateBetaSettingsOptions): Promise<void>;
244
+ createCodes(options: CreateBetaCodesOptions): Promise<BetaInviteCode[]>;
245
+ listCodes(options?: ListBetaCodesOptions): Promise<BetaInviteCode[]>;
246
+ getCode(code: string): Promise<BetaInviteCode | null>;
247
+ revokeCode(code: string): Promise<void>;
248
+ validateCode(code: string): Promise<BetaValidationResult>;
249
+ consumeCode(code: string, userId: string): Promise<BetaConsumeResult>;
250
+ isBetaTester(userId: string): Promise<boolean>;
251
+ getBetaTester(userId: string): Promise<BetaTester | null>;
252
+ listBetaTesters(options?: {
253
+ offset?: number;
254
+ limit?: number;
255
+ }): Promise<BetaTester[]>;
256
+ getStats(): Promise<BetaStats>;
257
+ getCodeUsageReports(): Promise<BetaCodeUsageReport[]>;
258
+ healthCheck(): Promise<boolean>;
259
+ /** Clear all data (for testing) */
260
+ clear(): void;
261
+ /** Get the number of stored codes */
262
+ get codeCount(): number;
263
+ /** Get the number of beta testers */
264
+ get testerCount(): number;
265
+ }
89
266
 
90
267
  /**
91
268
  * API Utilities
@@ -1279,6 +1456,100 @@ declare function createAuditLogger(options?: OpsAuditLoggerOptions): {
1279
1456
  };
1280
1457
  };
1281
1458
 
1459
+ /**
1460
+ * Beta Client Utilities
1461
+ *
1462
+ * Shared client-side helpers for beta access management.
1463
+ * These run in the browser and talk to your app's beta API endpoints.
1464
+ *
1465
+ * Standardizes the pattern used across DLL, WIAN, and future apps:
1466
+ * - Fetch beta settings from API
1467
+ * - Validate invite codes
1468
+ * - Store/retrieve beta code across OAuth redirect flows (sessionStorage)
1469
+ *
1470
+ * @example
1471
+ * ```typescript
1472
+ * import {
1473
+ * fetchBetaSettings,
1474
+ * validateBetaCode,
1475
+ * storeBetaCode,
1476
+ * getStoredBetaCode,
1477
+ * clearStoredBetaCode,
1478
+ * } from '@digilogiclabs/platform-core/auth';
1479
+ *
1480
+ * // On sign-in page mount
1481
+ * const settings = await fetchBetaSettings();
1482
+ * if (settings.requireInviteCode) {
1483
+ * const result = await validateBetaCode(userInput);
1484
+ * if (result.valid) {
1485
+ * storeBetaCode(userInput); // Survives OAuth redirect
1486
+ * // Proceed with sign-in
1487
+ * }
1488
+ * }
1489
+ * ```
1490
+ */
1491
+
1492
+ interface BetaClientConfig {
1493
+ /** Base URL for API calls (default: '' for same-origin) */
1494
+ baseUrl?: string;
1495
+ /** API endpoint for settings (default: '/api/beta-settings') */
1496
+ settingsEndpoint?: string;
1497
+ /** API endpoint for validation (default: '/api/validate-beta-code') */
1498
+ validateEndpoint?: string;
1499
+ /** sessionStorage key for storing beta code (default: 'beta_code') */
1500
+ storageKey?: string;
1501
+ /** Default settings to use when fetch fails */
1502
+ failSafeDefaults?: Partial<BetaSettings>;
1503
+ }
1504
+ /**
1505
+ * Create a configured beta client with app-specific settings.
1506
+ *
1507
+ * @example
1508
+ * ```typescript
1509
+ * // DLL app
1510
+ * const betaClient = createBetaClient({
1511
+ * storageKey: 'dll_beta_code',
1512
+ * validateEndpoint: '/api/validate-beta-code',
1513
+ * });
1514
+ *
1515
+ * // WIAN app
1516
+ * const betaClient = createBetaClient({
1517
+ * storageKey: 'wian_beta_code',
1518
+ * validateEndpoint: '/api/validate-invite-code',
1519
+ * });
1520
+ * ```
1521
+ */
1522
+ declare function createBetaClient(config?: BetaClientConfig): {
1523
+ fetchSettings: () => Promise<BetaSettings>;
1524
+ validateCode: (code: string) => Promise<BetaValidationResult>;
1525
+ storeCode: (code: string) => void;
1526
+ getStoredCode: () => string | null;
1527
+ clearStoredCode: () => void;
1528
+ };
1529
+ /**
1530
+ * Fetch beta settings from the server.
1531
+ * Returns fail-safe defaults if the fetch fails.
1532
+ */
1533
+ declare function fetchBetaSettings(config?: BetaClientConfig): Promise<BetaSettings>;
1534
+ /**
1535
+ * Validate a beta invite code against the server.
1536
+ * Handles rate limiting (429) gracefully.
1537
+ */
1538
+ declare function validateBetaCode(code: string, config?: BetaClientConfig): Promise<BetaValidationResult>;
1539
+ /**
1540
+ * Store a validated beta code in sessionStorage.
1541
+ * Used to pass the code through OAuth redirect flows.
1542
+ */
1543
+ declare function storeBetaCode(code: string, config?: BetaClientConfig): void;
1544
+ /**
1545
+ * Retrieve stored beta code from sessionStorage.
1546
+ */
1547
+ declare function getStoredBetaCode(config?: BetaClientConfig): string | null;
1548
+ /**
1549
+ * Clear stored beta code from sessionStorage.
1550
+ */
1551
+ declare function clearStoredBetaCode(config?: BetaClientConfig): void;
1552
+
1282
1553
  /**
1283
1554
  * Environment Variable Helpers
1284
1555
  *
@@ -1364,4 +1635,4 @@ declare function checkEnvVars(config: EnvValidationConfig): EnvValidationResult;
1364
1635
  */
1365
1636
  declare function getEnvSummary(keys: string[]): Record<string, boolean>;
1366
1637
 
1367
- export { type SecuritySession as $, ApiError as A, parseKeycloakRoles as B, CommonApiErrors as C, hasRole as D, type EnvValidationConfig as E, hasAnyRole as F, hasAllRoles as G, isTokenExpired as H, buildTokenRefreshParams as I, getTokenEndpoint as J, type KeycloakConfig as K, getEndSessionEndpoint as L, refreshKeycloakToken as M, type KeycloakCallbacksConfig as N, type KeycloakJwtFields as O, type AuthCookiesConfig as P, buildAuthCookies as Q, type RateLimitStore as R, type RedirectCallbackConfig as S, type TokenRefreshResult as T, buildRedirectCallback as U, buildKeycloakCallbacks as V, type AuthMethod as W, type RouteAuditConfig as X, type RateLimitPreset as Y, StandardRateLimitPresets as Z, type ApiSecurityConfig as _, type RateLimitRule as a, type ApiSecurityContext as a0, resolveRateLimitIdentifier as a1, extractClientIp as a2, buildRateLimitHeaders as a3, buildErrorBody as a4, WrapperPresets as a5, EmailSchema as a6, PasswordSchema as a7, SlugSchema as a8, PhoneSchema as a9, checkRateLimit as aA, getRateLimitStatus as aB, resetRateLimitForKey as aC, buildRateLimitResponseHeaders as aD, resolveIdentifier as aE, type OpsAuditActor as aF, type OpsAuditResource as aG, type OpsAuditEvent as aH, type OpsAuditRecord as aI, type OpsAuditLoggerOptions as aJ, type AuditRequest as aK, StandardAuditActions as aL, type StandardAuditActionType as aM, extractAuditIp as aN, extractAuditUserAgent as aO, extractAuditRequestId as aP, createAuditActor as aQ, createAuditLogger as aR, defangUrl as aS, sanitizeForEmail as aT, URL_PROTOCOL_PATTERN as aU, URL_DOMAIN_PATTERN as aV, HTML_TAG_PATTERN as aW, PG_ERROR_MAP as aX, PersonNameSchema as aa, createSafeTextSchema as ab, PaginationSchema as ac, DateRangeSchema as ad, SearchQuerySchema as ae, LoginSchema as af, SignupSchema as ag, type EmailInput as ah, type PaginationInput as ai, type DateRangeInput as aj, type SearchQueryInput as ak, type LoginInput as al, type SignupInput as am, type DeploymentStage as an, type FlagValue as ao, type FlagDefinition as ap, type FlagDefinitions as aq, type ResolvedFlags as ar, type AllowlistConfig as as, detectStage as at, createFeatureFlags as au, buildAllowlist as av, isAllowlisted as aw, type RateLimitCheckResult as ax, CommonRateLimits as ay, createMemoryRateLimitStore as az, type RateLimitOptions as b, constantTimeEqual as c, containsUrls as d, escapeHtml as e, containsHtml as f, sanitizeApiError as g, getCorrelationId as h, classifyError as i, isApiError as j, ApiErrorCode as k, buildPagination as l, type ApiErrorCodeType as m, type ApiSuccessResponse as n, type ApiPaginatedResponse as o, getRequiredEnv as p, getOptionalEnv as q, getBoolEnv as r, stripHtml as s, getIntEnv as t, checkEnvVars as u, validateEnvVars as v, getEnvSummary as w, type EnvValidationResult as x, type KeycloakTokenSet as y, KEYCLOAK_DEFAULT_ROLES as z };
1638
+ export { EmailSchema as $, ApiError as A, getEndSessionEndpoint as B, CommonApiErrors as C, refreshKeycloakToken as D, type EnvValidationConfig as E, type KeycloakCallbacksConfig as F, type KeycloakJwtFields as G, type AuthCookiesConfig as H, buildAuthCookies as I, type RedirectCallbackConfig as J, type KeycloakConfig as K, buildRedirectCallback as L, buildKeycloakCallbacks as M, type AuthMethod as N, type RouteAuditConfig as O, type RateLimitPreset as P, type ApiSecurityConfig as Q, type RateLimitStore as R, StandardRateLimitPresets as S, type TokenRefreshResult as T, type SecuritySession as U, type ApiSecurityContext as V, resolveRateLimitIdentifier as W, extractClientIp as X, buildRateLimitHeaders as Y, buildErrorBody as Z, WrapperPresets as _, type RateLimitRule as a, type BetaTester as a$, PasswordSchema as a0, SlugSchema as a1, PhoneSchema as a2, PersonNameSchema as a3, createSafeTextSchema as a4, PaginationSchema as a5, DateRangeSchema as a6, SearchQuerySchema as a7, LoginSchema as a8, SignupSchema as a9, type OpsAuditEvent as aA, type OpsAuditRecord as aB, type OpsAuditLoggerOptions as aC, type AuditRequest as aD, StandardAuditActions as aE, type StandardAuditActionType as aF, extractAuditIp as aG, extractAuditUserAgent as aH, extractAuditRequestId as aI, createAuditActor as aJ, createAuditLogger as aK, type BetaClientConfig as aL, createBetaClient as aM, fetchBetaSettings as aN, validateBetaCode as aO, storeBetaCode as aP, getStoredBetaCode as aQ, clearStoredBetaCode as aR, type IBeta as aS, type BetaConfig as aT, type BetaSettings as aU, type UpdateBetaSettingsOptions as aV, type CreateBetaCodesOptions as aW, type BetaInviteCode as aX, type ListBetaCodesOptions as aY, type BetaValidationResult as aZ, type BetaConsumeResult as a_, type EmailInput as aa, type PaginationInput as ab, type DateRangeInput as ac, type SearchQueryInput as ad, type LoginInput as ae, type SignupInput as af, type DeploymentStage as ag, type FlagValue as ah, type FlagDefinition as ai, type FlagDefinitions as aj, type ResolvedFlags as ak, type AllowlistConfig as al, detectStage as am, createFeatureFlags as an, buildAllowlist as ao, isAllowlisted as ap, type RateLimitCheckResult as aq, CommonRateLimits as ar, createMemoryRateLimitStore as as, checkRateLimit as at, getRateLimitStatus as au, resetRateLimitForKey as av, buildRateLimitResponseHeaders as aw, resolveIdentifier as ax, type OpsAuditActor as ay, type OpsAuditResource as az, type RateLimitOptions as b, type BetaStats as b0, type BetaCodeUsageReport as b1, MemoryBeta as b2, generateBetaCode as b3, normalizeBetaCode as b4, generateBetaId as b5, type BetaCodeStatus as b6, PG_ERROR_MAP as b7, classifyError as c, ApiErrorCode as d, buildPagination as e, type ApiErrorCodeType as f, type ApiSuccessResponse as g, type ApiPaginatedResponse as h, isApiError as i, getRequiredEnv as j, getOptionalEnv as k, getBoolEnv as l, getIntEnv as m, checkEnvVars as n, getEnvSummary as o, type EnvValidationResult as p, type KeycloakTokenSet as q, KEYCLOAK_DEFAULT_ROLES as r, parseKeycloakRoles as s, hasRole as t, hasAnyRole as u, validateEnvVars as v, hasAllRoles as w, isTokenExpired as x, buildTokenRefreshParams as y, getTokenEndpoint as z };