@digilogiclabs/platform-core 1.3.0 → 1.5.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/README.md +79 -3
- package/dist/{ConsoleEmail-hUDFsKoA.d.mts → ConsoleEmail-ubSVWgTa.d.mts} +187 -1
- package/dist/{ConsoleEmail-hUDFsKoA.d.ts → ConsoleEmail-ubSVWgTa.d.ts} +187 -1
- package/dist/index.d.mts +1583 -130
- package/dist/index.d.ts +1583 -130
- package/dist/index.js +1978 -169
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1922 -162
- package/dist/index.mjs.map +1 -1
- package/dist/migrate.js +3 -2
- package/dist/migrate.js.map +1 -1
- package/dist/security-headers.d.mts +75 -0
- package/dist/security-headers.d.ts +75 -0
- package/dist/security-headers.js +137 -0
- package/dist/security-headers.js.map +1 -0
- package/dist/security-headers.mjs +111 -0
- package/dist/security-headers.mjs.map +1 -0
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +196 -15
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +200 -14
- package/dist/testing.mjs.map +1 -1
- package/package.json +16 -11
package/dist/index.d.mts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { p as ILogger, q as IMetrics, I as IPlatform, P as PlatformHealthStatus, u as MetricsSummary, e as IDatabase, k as IQueryBuilder, Q as QueryResult, l as ICache, m as IStorage, U as UploadOptions, S as StorageFile, n as IEmail, t as EmailMessage,
|
|
2
|
-
export {
|
|
1
|
+
import { p as ILogger, q as IMetrics, I as IPlatform, P as PlatformHealthStatus, u as MetricsSummary, v as ICrypto, w as EncryptOptions, x as EncryptedField, D as DeterministicEncryptedField, K as KeyRotationResult, y as CryptoKeyMetadata, e as IDatabase, k as IQueryBuilder, Q as QueryResult, l as ICache, m as IStorage, U as UploadOptions, S as StorageFile, n as IEmail, t as EmailMessage, z as EmailResult, o as IQueue, s as JobOptions, J as Job, R as RepeatOptions, A as JobState, B as JobEventType, F as JobEventHandler, G as IAI, H as AIConfig, L as AIChatRequest, O as AIChatResponse, T as AIStreamChunk, V as AIStreamCallback, W as AICompletionRequest, X as AICompletionResponse, Y as AIEmbeddingRequest, Z as AIEmbeddingResponse, _ as AIModelConfig, $ as AIModelType, a0 as AIProvider, a1 as IRAG, a2 as RAGConfig, a3 as CreateCollectionOptions, a4 as RAGCollection, a5 as RAGDocument, a6 as IngestionOptions, a7 as BulkIngestionResult, a8 as IngestionResult, a9 as DocumentStatus, aa as RAGChunk, ab as RAGSearchQuery, ac as RAGSearchResponse, ad as RAGSearchResult, ae as ContextAssemblyConfig, af as AssembledContext, ag as RAGPipeline } from './ConsoleEmail-ubSVWgTa.mjs';
|
|
2
|
+
export { aI as AIChatChoice, br as AIConfigSchema, aO as AIError, aN as AIErrorCode, aC as AIErrorMessages, aJ as AIFinishReason, aF as AIMessage, bk as AIProviderSchema, aE as AIRole, aM as AIRouterConfig, aH as AITool, aG as AIToolCall, aK as AIUsageInfo, am as BackoffOptions, by as BulkheadConfigSchema, bI as CacheConfig, bn as CacheConfigSchema, be as CacheProviderSchema, aS as ChunkingConfig, aQ as ChunkingPresets, aR as ChunkingStrategy, bw as CircuitBreakerConfigSchema, C as ConsoleEmail, h as ConsoleLogger, aX as CryptoAlgorithm, bP as CryptoConfig, bt as CryptoConfigSchema, aW as CryptoKeyStatus, bH as DatabaseConfig, bm as DatabaseConfigSchema, bd as DatabaseProviderSchema, b7 as EmailAddress, b8 as EmailAttachment, bK as EmailConfig, bp as EmailConfigSchema, bg as EmailProviderSchema, E as EnvSecrets, aw as GetSecretOptions, as as HistogramStats, ah as ICacheOptions, r as ISecrets, b1 as ISpan, b0 as ITracing, aj as JobContext, ak as JobEvent, ai as JobResult, ap as LogEntry, an as LogLevel, bj as LogLevelSchema, ao as LogMeta, aq as LoggerConfig, bA as LoggingConfigSchema, aD as MemoryAI, a as MemoryCache, M as MemoryDatabase, c as MemoryEmail, i as MemoryMetrics, d as MemoryQueue, aP as MemoryRAG, f as MemorySecrets, b as MemoryStorage, a_ as MemoryTracing, ar as MetricTags, bB as MetricsConfigSchema, bO as MiddlewareConfig, bE as MiddlewareConfigSchema, N as NoopLogger, j as NoopMetrics, a$ as NoopTracing, bN as ObservabilityConfig, bD as ObservabilityConfigSchema, bG as PlatformConfig, bF as PlatformConfigSchema, bL as QueueConfig, bq as QueueConfigSchema, bh as QueueProviderSchema, al as QueueStats, bs as RAGConfigSchema, aU as RAGFilter, aV as RAGPipelineStep, bl as RAGProviderSchema, bM as ResilienceConfig, bz as ResilienceConfigSchema, bv as RetryConfigSchema, ay as RotateSecretOptions, az as RotationResult, aL as RoutingStrategy, aT as SearchMode, au as Secret, av as SecretMetadata, bQ as SecurityConfig, bu as SecurityConfigSchema, ax as SetSecretOptions, b2 as SpanContext, bc as SpanEvent, b5 as SpanKind, b3 as SpanOptions, b4 as SpanStatus, bb as SpanStatusCode, bJ as StorageConfig, bo as StorageConfigSchema, bf as StorageProviderSchema, bx as TimeoutConfigSchema, at as TimingStats, b6 as TracingConfig, bC as TracingConfigSchema, bi as TracingProviderSchema, b9 as calculateBackoff, aA as createAIError, g as createPlatform, aY as createPlatformAsync, aZ as createScopedMetrics, ba as generateJobId, bU as getDefaultConfig, aB as isAIError, bR as loadConfig, bT as safeValidateConfig, bS as validateConfig } from './ConsoleEmail-ubSVWgTa.mjs';
|
|
3
3
|
export { t as IMigrationDatabase, I as IMigrator, n as Migration, o as MigrationRecord, p as MigrationResult, q as MigrationStatus, M as Migrator, r as MigratorConfig, S as SQL, f as createDomainVerificationsTable, c as createMigration, b as createSsoOidcConfigsTable, m as createSsoSessionsTable, k as createTenantInvitationsTable, j as createTenantMembersTable, l as createTenantUsageTable, i as createTenantsTable, h as createVerifiedDomainsTable, d as defineMigration, e as enterpriseMigrations, g as generateVersion, a as getEnterpriseMigrations, s as sqlMigration } from './index-CepDdu7h.mjs';
|
|
4
|
+
export { NextHeaderEntry, SecurityHeaderPresets, SecurityHeadersConfig, generateSecurityHeaders } from './security-headers.mjs';
|
|
5
|
+
import { z } from 'zod';
|
|
4
6
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
5
7
|
import { Pool } from 'pg';
|
|
6
8
|
import { Redis } from '@upstash/redis';
|
|
7
|
-
import { Redis as Redis$1 } from 'ioredis';
|
|
9
|
+
import Redis$2, { Redis as Redis$1 } from 'ioredis';
|
|
8
10
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
9
11
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
10
12
|
import { Resend } from 'resend';
|
|
11
13
|
import Stripe from 'stripe';
|
|
12
|
-
import 'zod';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Health Check Interface
|
|
@@ -945,7 +946,7 @@ type DeliveryStatus = "pending" | "success" | "failed" | "skipped";
|
|
|
945
946
|
/**
|
|
946
947
|
* Signature algorithm
|
|
947
948
|
*/
|
|
948
|
-
type SignatureAlgorithm = "sha256" | "sha512"
|
|
949
|
+
type SignatureAlgorithm = "sha256" | "sha512";
|
|
949
950
|
/**
|
|
950
951
|
* Registered webhook endpoint
|
|
951
952
|
*/
|
|
@@ -9009,7 +9010,7 @@ type RateLimitAlgorithm = "fixed-window" | "sliding-window" | "token-bucket";
|
|
|
9009
9010
|
/**
|
|
9010
9011
|
* Rate limiting options
|
|
9011
9012
|
*/
|
|
9012
|
-
interface RateLimitOptions {
|
|
9013
|
+
interface RateLimitOptions$1 {
|
|
9013
9014
|
/** Maximum requests per window */
|
|
9014
9015
|
limit: number;
|
|
9015
9016
|
/** Time window in milliseconds */
|
|
@@ -9033,7 +9034,7 @@ interface RateLimitOptions {
|
|
|
9033
9034
|
* Rate limiting middleware
|
|
9034
9035
|
* Prevents abuse by limiting request frequency
|
|
9035
9036
|
*/
|
|
9036
|
-
declare function createRateLimitMiddleware(options: RateLimitOptions): Middleware;
|
|
9037
|
+
declare function createRateLimitMiddleware(options: RateLimitOptions$1): Middleware;
|
|
9037
9038
|
/**
|
|
9038
9039
|
* Create an IP-based rate limiter key generator
|
|
9039
9040
|
*/
|
|
@@ -9045,7 +9046,7 @@ declare function createUserKeyGenerator(getUserId: (ctx: MiddlewareContext) => s
|
|
|
9045
9046
|
/**
|
|
9046
9047
|
* Sliding window rate limiter options
|
|
9047
9048
|
*/
|
|
9048
|
-
interface SlidingWindowRateLimitOptions extends Omit<RateLimitOptions, "algorithm"> {
|
|
9049
|
+
interface SlidingWindowRateLimitOptions extends Omit<RateLimitOptions$1, "algorithm"> {
|
|
9049
9050
|
/** Number of sub-windows (more = more accurate, more memory) */
|
|
9050
9051
|
precision?: number;
|
|
9051
9052
|
}
|
|
@@ -9235,7 +9236,6 @@ declare const runWithContext: <T>(data: CorrelationData, fn: () => T) => T;
|
|
|
9235
9236
|
declare const runWithContextAsync: <T>(data: CorrelationData, fn: () => Promise<T>) => Promise<T>;
|
|
9236
9237
|
declare const getContext: () => CorrelationData | undefined;
|
|
9237
9238
|
declare const getTraceId: () => string | undefined;
|
|
9238
|
-
declare const getCorrelationId: () => string | undefined;
|
|
9239
9239
|
declare const getRequestId: () => string | undefined;
|
|
9240
9240
|
declare const getUserId: () => string | undefined;
|
|
9241
9241
|
declare const getTenantId: () => string | undefined;
|
|
@@ -10161,144 +10161,1306 @@ declare function withFallbackChain<T>(primary: () => Promise<T>, fallbacks: Arra
|
|
|
10161
10161
|
/**
|
|
10162
10162
|
* Common fallback strategies
|
|
10163
10163
|
*/
|
|
10164
|
-
declare const FallbackStrategies: {
|
|
10165
|
-
/**
|
|
10166
|
-
* Return empty array
|
|
10167
|
-
*/
|
|
10168
|
-
emptyArray: <T>() => FallbackOptions<T[]>;
|
|
10169
|
-
/**
|
|
10170
|
-
* Return null
|
|
10171
|
-
*/
|
|
10172
|
-
nullable: <T>() => FallbackOptions<T | null>;
|
|
10173
|
-
/**
|
|
10174
|
-
* Return default value
|
|
10175
|
-
*/
|
|
10176
|
-
defaultValue: <T>(value: T) => FallbackOptions<T>;
|
|
10164
|
+
declare const FallbackStrategies: {
|
|
10165
|
+
/**
|
|
10166
|
+
* Return empty array
|
|
10167
|
+
*/
|
|
10168
|
+
emptyArray: <T>() => FallbackOptions<T[]>;
|
|
10169
|
+
/**
|
|
10170
|
+
* Return null
|
|
10171
|
+
*/
|
|
10172
|
+
nullable: <T>() => FallbackOptions<T | null>;
|
|
10173
|
+
/**
|
|
10174
|
+
* Return default value
|
|
10175
|
+
*/
|
|
10176
|
+
defaultValue: <T>(value: T) => FallbackOptions<T>;
|
|
10177
|
+
/**
|
|
10178
|
+
* Return cached value from a cache function
|
|
10179
|
+
*/
|
|
10180
|
+
fromCache: <T>(getCached: () => Promise<T | null>, defaultValue: T) => FallbackOptions<T>;
|
|
10181
|
+
/**
|
|
10182
|
+
* Degrade gracefully with partial data
|
|
10183
|
+
*/
|
|
10184
|
+
degrade: <T>(getDegraded: (error: Error) => T) => FallbackOptions<T>;
|
|
10185
|
+
};
|
|
10186
|
+
|
|
10187
|
+
/**
|
|
10188
|
+
* Security Utilities
|
|
10189
|
+
*
|
|
10190
|
+
* HTML escaping, input detection, sanitization helpers,
|
|
10191
|
+
* timing-safe comparison, error sanitization, and request
|
|
10192
|
+
* correlation for safe, consistent security across all apps.
|
|
10193
|
+
*/
|
|
10194
|
+
/** Regex for protocol-prefixed URLs */
|
|
10195
|
+
declare const URL_PROTOCOL_PATTERN: RegExp;
|
|
10196
|
+
/** Regex for bare domain names with common TLDs */
|
|
10197
|
+
declare const URL_DOMAIN_PATTERN: RegExp;
|
|
10198
|
+
/** Regex for HTML tags */
|
|
10199
|
+
declare const HTML_TAG_PATTERN: RegExp;
|
|
10200
|
+
/**
|
|
10201
|
+
* Escape HTML special characters to prevent injection.
|
|
10202
|
+
* Use when inserting user content into HTML email templates or rendered HTML.
|
|
10203
|
+
*/
|
|
10204
|
+
declare function escapeHtml(str: string): string;
|
|
10205
|
+
/** Check if a string contains protocol-prefixed URLs or bare domains */
|
|
10206
|
+
declare function containsUrls(str: string): boolean;
|
|
10207
|
+
/** Check if a string contains HTML tags */
|
|
10208
|
+
declare function containsHtml(str: string): boolean;
|
|
10209
|
+
/** Strip all HTML tags from a string */
|
|
10210
|
+
declare function stripHtml(str: string): string;
|
|
10211
|
+
/**
|
|
10212
|
+
* Defang URLs to prevent auto-linking in email clients.
|
|
10213
|
+
* Converts https://evil.com → hxxps://evil[.]com
|
|
10214
|
+
*/
|
|
10215
|
+
declare function defangUrl(str: string): string;
|
|
10216
|
+
/**
|
|
10217
|
+
* Sanitize user content for safe insertion into HTML email templates.
|
|
10218
|
+
* Escapes HTML entities AND defangs any URLs that slipped through validation.
|
|
10219
|
+
*/
|
|
10220
|
+
declare function sanitizeForEmail(str: string): string;
|
|
10221
|
+
/**
|
|
10222
|
+
* Constant-time string comparison to prevent timing side-channel attacks.
|
|
10223
|
+
* Use for comparing secrets, tokens, API keys, HMAC signatures, etc.
|
|
10224
|
+
*
|
|
10225
|
+
* Returns false (not throws) for length mismatches — still constant-time
|
|
10226
|
+
* relative to the shorter string to avoid leaking length info.
|
|
10227
|
+
*
|
|
10228
|
+
* @example
|
|
10229
|
+
* ```typescript
|
|
10230
|
+
* if (!constantTimeEqual(providedToken, expectedSecret)) {
|
|
10231
|
+
* return { status: 401, error: 'Invalid token' }
|
|
10232
|
+
* }
|
|
10233
|
+
* ```
|
|
10234
|
+
*/
|
|
10235
|
+
declare function constantTimeEqual(a: string, b: string): boolean;
|
|
10236
|
+
/**
|
|
10237
|
+
* Sanitize an error for client-facing API responses.
|
|
10238
|
+
*
|
|
10239
|
+
* - 4xx errors: returns the actual message (client needs to know what went wrong)
|
|
10240
|
+
* - 5xx errors: returns a generic message (never leak internals to clients)
|
|
10241
|
+
* - Development mode: optionally includes stack trace for debugging
|
|
10242
|
+
*
|
|
10243
|
+
* @example
|
|
10244
|
+
* ```typescript
|
|
10245
|
+
* catch (error) {
|
|
10246
|
+
* const { message, code } = sanitizeApiError(error, 500)
|
|
10247
|
+
* return Response.json({ error: message, code }, { status: 500 })
|
|
10248
|
+
* }
|
|
10249
|
+
* ```
|
|
10250
|
+
*/
|
|
10251
|
+
declare function sanitizeApiError(error: unknown, statusCode: number, isDevelopment?: boolean): {
|
|
10252
|
+
message: string;
|
|
10253
|
+
code?: string;
|
|
10254
|
+
stack?: string;
|
|
10255
|
+
};
|
|
10256
|
+
/**
|
|
10257
|
+
* Extract a correlation/request ID from standard headers, or generate one.
|
|
10258
|
+
*
|
|
10259
|
+
* Checks (in order): X-Request-ID, X-Correlation-ID, then falls back to
|
|
10260
|
+
* crypto.randomUUID(). Works with any headers-like object (plain object,
|
|
10261
|
+
* Headers API, or a getter function).
|
|
10262
|
+
*
|
|
10263
|
+
* @example
|
|
10264
|
+
* ```typescript
|
|
10265
|
+
* // With Next.js request
|
|
10266
|
+
* const id = getCorrelationId((name) => request.headers.get(name))
|
|
10267
|
+
*
|
|
10268
|
+
* // With plain object
|
|
10269
|
+
* const id = getCorrelationId({ 'x-request-id': 'abc-123' })
|
|
10270
|
+
* ```
|
|
10271
|
+
*/
|
|
10272
|
+
declare function getCorrelationId(headers: Record<string, string | string[] | undefined> | ((name: string) => string | null | undefined)): string;
|
|
10273
|
+
|
|
10274
|
+
/**
|
|
10275
|
+
* API Utilities
|
|
10276
|
+
*
|
|
10277
|
+
* Framework-agnostic error codes, error class, response types,
|
|
10278
|
+
* and database error mapping for consistent API behavior across apps.
|
|
10279
|
+
*/
|
|
10280
|
+
/** Standard API error codes */
|
|
10281
|
+
declare const ApiErrorCode: {
|
|
10282
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
10283
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
10284
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
10285
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
10286
|
+
readonly CONFLICT: "CONFLICT";
|
|
10287
|
+
readonly RATE_LIMIT_EXCEEDED: "RATE_LIMIT_EXCEEDED";
|
|
10288
|
+
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
10289
|
+
readonly DATABASE_ERROR: "DATABASE_ERROR";
|
|
10290
|
+
readonly EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR";
|
|
10291
|
+
readonly CONFIGURATION_ERROR: "CONFIGURATION_ERROR";
|
|
10292
|
+
};
|
|
10293
|
+
type ApiErrorCodeType = (typeof ApiErrorCode)[keyof typeof ApiErrorCode];
|
|
10294
|
+
/** Custom API Error class with status code and error code */
|
|
10295
|
+
declare class ApiError extends Error {
|
|
10296
|
+
readonly statusCode: number;
|
|
10297
|
+
readonly code: ApiErrorCodeType;
|
|
10298
|
+
readonly details?: unknown;
|
|
10299
|
+
constructor(statusCode: number, message: string, code?: ApiErrorCodeType, details?: unknown);
|
|
10300
|
+
}
|
|
10301
|
+
/** Type guard for ApiError */
|
|
10302
|
+
declare function isApiError(error: unknown): error is ApiError;
|
|
10303
|
+
/** Pre-built error factories */
|
|
10304
|
+
declare const CommonApiErrors: {
|
|
10305
|
+
unauthorized: (msg?: string) => ApiError;
|
|
10306
|
+
forbidden: (msg?: string) => ApiError;
|
|
10307
|
+
notFound: (resource?: string) => ApiError;
|
|
10308
|
+
conflict: (msg?: string) => ApiError;
|
|
10309
|
+
rateLimitExceeded: (msg?: string) => ApiError;
|
|
10310
|
+
validationError: (details?: unknown) => ApiError;
|
|
10311
|
+
internalError: (msg?: string) => ApiError;
|
|
10312
|
+
};
|
|
10313
|
+
/** PostgreSQL error code → HTTP status mapping */
|
|
10314
|
+
declare const PG_ERROR_MAP: Record<string, {
|
|
10315
|
+
status: number;
|
|
10316
|
+
code: ApiErrorCodeType;
|
|
10317
|
+
message: string;
|
|
10318
|
+
}>;
|
|
10319
|
+
/**
|
|
10320
|
+
* Classify any error into a standardized shape.
|
|
10321
|
+
* Framework-agnostic — returns a plain object, not an HTTP response.
|
|
10322
|
+
*/
|
|
10323
|
+
declare function classifyError(error: unknown, isDev?: boolean): {
|
|
10324
|
+
status: number;
|
|
10325
|
+
body: {
|
|
10326
|
+
error: string;
|
|
10327
|
+
code: string;
|
|
10328
|
+
details?: unknown;
|
|
10329
|
+
};
|
|
10330
|
+
};
|
|
10331
|
+
/** Standard success response shape */
|
|
10332
|
+
interface ApiSuccessResponse<T = unknown> {
|
|
10333
|
+
success: true;
|
|
10334
|
+
data: T;
|
|
10335
|
+
message?: string;
|
|
10336
|
+
timestamp?: string;
|
|
10337
|
+
}
|
|
10338
|
+
/** Standard paginated response shape */
|
|
10339
|
+
interface ApiPaginatedResponse<T = unknown> extends ApiSuccessResponse<T[]> {
|
|
10340
|
+
pagination: {
|
|
10341
|
+
page: number;
|
|
10342
|
+
limit: number;
|
|
10343
|
+
total: number;
|
|
10344
|
+
totalPages: number;
|
|
10345
|
+
hasMore: boolean;
|
|
10346
|
+
};
|
|
10347
|
+
}
|
|
10348
|
+
/** Build a pagination metadata object */
|
|
10349
|
+
declare function buildPagination(page: number, limit: number, total: number): {
|
|
10350
|
+
page: number;
|
|
10351
|
+
limit: number;
|
|
10352
|
+
total: number;
|
|
10353
|
+
totalPages: number;
|
|
10354
|
+
hasMore: boolean;
|
|
10355
|
+
};
|
|
10356
|
+
|
|
10357
|
+
/**
|
|
10358
|
+
* Keycloak Authentication Utilities
|
|
10359
|
+
*
|
|
10360
|
+
* Framework-agnostic helpers for working with Keycloak OIDC tokens.
|
|
10361
|
+
* Used by Next.js apps (Auth.js middleware + API routes) and .NET services
|
|
10362
|
+
* share the same role model — these helpers ensure consistent behavior.
|
|
10363
|
+
*
|
|
10364
|
+
* Edge-runtime compatible: uses atob() for JWT decoding, not Buffer.
|
|
10365
|
+
*/
|
|
10366
|
+
/**
|
|
10367
|
+
* Keycloak provider configuration for Auth.js / NextAuth.
|
|
10368
|
+
* Everything needed to configure the Keycloak OIDC provider.
|
|
10369
|
+
*/
|
|
10370
|
+
interface KeycloakConfig {
|
|
10371
|
+
/** Keycloak issuer URL (e.g. https://auth.example.com/realms/my-realm) */
|
|
10372
|
+
issuer: string;
|
|
10373
|
+
/** OAuth client ID registered in Keycloak */
|
|
10374
|
+
clientId: string;
|
|
10375
|
+
/** OAuth client secret */
|
|
10376
|
+
clientSecret: string;
|
|
10377
|
+
}
|
|
10378
|
+
/**
|
|
10379
|
+
* Token set returned by Keycloak after authentication or refresh.
|
|
10380
|
+
*/
|
|
10381
|
+
interface KeycloakTokenSet {
|
|
10382
|
+
accessToken: string;
|
|
10383
|
+
refreshToken?: string;
|
|
10384
|
+
idToken?: string;
|
|
10385
|
+
/** Expiry as epoch milliseconds */
|
|
10386
|
+
expiresAt: number;
|
|
10387
|
+
/** Parsed realm roles (filtered, no Keycloak defaults) */
|
|
10388
|
+
roles: string[];
|
|
10389
|
+
}
|
|
10390
|
+
/**
|
|
10391
|
+
* Result of a token refresh attempt.
|
|
10392
|
+
*/
|
|
10393
|
+
type TokenRefreshResult = {
|
|
10394
|
+
ok: true;
|
|
10395
|
+
tokens: KeycloakTokenSet;
|
|
10396
|
+
} | {
|
|
10397
|
+
ok: false;
|
|
10398
|
+
error: string;
|
|
10399
|
+
};
|
|
10400
|
+
/**
|
|
10401
|
+
* Default Keycloak roles that should be filtered out when checking
|
|
10402
|
+
* application-level roles. These are always present and not meaningful
|
|
10403
|
+
* for authorization decisions.
|
|
10404
|
+
*/
|
|
10405
|
+
declare const KEYCLOAK_DEFAULT_ROLES: readonly ["offline_access", "uma_authorization"];
|
|
10406
|
+
/**
|
|
10407
|
+
* Parse realm roles from a Keycloak JWT access token.
|
|
10408
|
+
*
|
|
10409
|
+
* Supports two token formats:
|
|
10410
|
+
* - `realm_roles` (flat array) — Custom client mapper configuration
|
|
10411
|
+
* - `realm_access.roles` (nested) — Keycloak default format
|
|
10412
|
+
*
|
|
10413
|
+
* Uses atob() for Edge runtime compatibility (not Buffer.from).
|
|
10414
|
+
* Filters out Keycloak default roles automatically.
|
|
10415
|
+
*
|
|
10416
|
+
* @param accessToken - Raw JWT string from Keycloak
|
|
10417
|
+
* @param additionalDefaultRoles - Extra role names to filter (e.g. realm-specific defaults)
|
|
10418
|
+
* @returns Array of meaningful role names
|
|
10419
|
+
*
|
|
10420
|
+
* @example
|
|
10421
|
+
* ```typescript
|
|
10422
|
+
* const roles = parseKeycloakRoles(account.access_token)
|
|
10423
|
+
* // ['admin', 'editor']
|
|
10424
|
+
*
|
|
10425
|
+
* // With realm-specific defaults
|
|
10426
|
+
* const roles = parseKeycloakRoles(token, ['default-roles-my-realm'])
|
|
10427
|
+
* ```
|
|
10428
|
+
*/
|
|
10429
|
+
declare function parseKeycloakRoles(accessToken: string | undefined | null, additionalDefaultRoles?: string[]): string[];
|
|
10430
|
+
/**
|
|
10431
|
+
* Check if a user has a specific role.
|
|
10432
|
+
*
|
|
10433
|
+
* @example
|
|
10434
|
+
* ```typescript
|
|
10435
|
+
* if (hasRole(session.user.roles, 'admin')) {
|
|
10436
|
+
* // grant access
|
|
10437
|
+
* }
|
|
10438
|
+
* ```
|
|
10439
|
+
*/
|
|
10440
|
+
declare function hasRole(roles: string[] | undefined | null, role: string): boolean;
|
|
10441
|
+
/**
|
|
10442
|
+
* Check if a user has ANY of the specified roles (OR logic).
|
|
10443
|
+
*
|
|
10444
|
+
* @example
|
|
10445
|
+
* ```typescript
|
|
10446
|
+
* if (hasAnyRole(session.user.roles, ['admin', 'editor'])) {
|
|
10447
|
+
* // grant access
|
|
10448
|
+
* }
|
|
10449
|
+
* ```
|
|
10450
|
+
*/
|
|
10451
|
+
declare function hasAnyRole(roles: string[] | undefined | null, requiredRoles: string[]): boolean;
|
|
10452
|
+
/**
|
|
10453
|
+
* Check if a user has ALL of the specified roles (AND logic).
|
|
10454
|
+
*
|
|
10455
|
+
* @example
|
|
10456
|
+
* ```typescript
|
|
10457
|
+
* if (hasAllRoles(session.user.roles, ['admin', 'billing'])) {
|
|
10458
|
+
* // grant access to billing admin
|
|
10459
|
+
* }
|
|
10460
|
+
* ```
|
|
10461
|
+
*/
|
|
10462
|
+
declare function hasAllRoles(roles: string[] | undefined | null, requiredRoles: string[]): boolean;
|
|
10463
|
+
/**
|
|
10464
|
+
* Check if a token needs refreshing.
|
|
10465
|
+
*
|
|
10466
|
+
* @param expiresAt - Token expiry as epoch milliseconds
|
|
10467
|
+
* @param bufferMs - Refresh this many ms before actual expiry (default: 60s)
|
|
10468
|
+
* @returns true if the token should be refreshed
|
|
10469
|
+
*/
|
|
10470
|
+
declare function isTokenExpired(expiresAt: number | undefined | null, bufferMs?: number): boolean;
|
|
10471
|
+
/**
|
|
10472
|
+
* Build the URLSearchParams for a Keycloak token refresh request.
|
|
10473
|
+
*
|
|
10474
|
+
* This is the body for POST to `{issuer}/protocol/openid-connect/token`.
|
|
10475
|
+
* Framework-agnostic — use with fetch(), axios, or any HTTP client.
|
|
10476
|
+
*
|
|
10477
|
+
* @example
|
|
10478
|
+
* ```typescript
|
|
10479
|
+
* const params = buildTokenRefreshParams(config, refreshToken)
|
|
10480
|
+
* const response = await fetch(`${config.issuer}/protocol/openid-connect/token`, {
|
|
10481
|
+
* method: 'POST',
|
|
10482
|
+
* headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
10483
|
+
* body: params,
|
|
10484
|
+
* })
|
|
10485
|
+
* ```
|
|
10486
|
+
*/
|
|
10487
|
+
declare function buildTokenRefreshParams(config: KeycloakConfig, refreshToken: string): URLSearchParams;
|
|
10488
|
+
/**
|
|
10489
|
+
* Get the Keycloak token endpoint URL for a given issuer.
|
|
10490
|
+
*/
|
|
10491
|
+
declare function getTokenEndpoint(issuer: string): string;
|
|
10492
|
+
/**
|
|
10493
|
+
* Get the Keycloak end session (logout) endpoint URL.
|
|
10494
|
+
*/
|
|
10495
|
+
declare function getEndSessionEndpoint(issuer: string): string;
|
|
10496
|
+
/**
|
|
10497
|
+
* Perform a token refresh against Keycloak and parse the result.
|
|
10498
|
+
*
|
|
10499
|
+
* Returns a discriminated union — check `result.ok` before accessing tokens.
|
|
10500
|
+
* Automatically parses roles from the new access token.
|
|
10501
|
+
*
|
|
10502
|
+
* @example
|
|
10503
|
+
* ```typescript
|
|
10504
|
+
* const result = await refreshKeycloakToken(config, currentRefreshToken)
|
|
10505
|
+
* if (result.ok) {
|
|
10506
|
+
* token.accessToken = result.tokens.accessToken
|
|
10507
|
+
* token.roles = result.tokens.roles
|
|
10508
|
+
* } else {
|
|
10509
|
+
* // Force re-login
|
|
10510
|
+
* token.error = 'RefreshTokenError'
|
|
10511
|
+
* }
|
|
10512
|
+
* ```
|
|
10513
|
+
*/
|
|
10514
|
+
declare function refreshKeycloakToken(config: KeycloakConfig, refreshToken: string, additionalDefaultRoles?: string[]): Promise<TokenRefreshResult>;
|
|
10515
|
+
|
|
10516
|
+
/**
|
|
10517
|
+
* Next.js Auth.js + Keycloak Configuration Builder
|
|
10518
|
+
*
|
|
10519
|
+
* Generates Auth.js callbacks for Keycloak OIDC integration.
|
|
10520
|
+
* Handles JWT token storage, role parsing, token refresh, and session mapping.
|
|
10521
|
+
*
|
|
10522
|
+
* Edge-runtime compatible: uses only atob() and fetch(), no Node.js-only APIs.
|
|
10523
|
+
*
|
|
10524
|
+
* @example
|
|
10525
|
+
* ```typescript
|
|
10526
|
+
* // auth.config.ts (Edge-compatible)
|
|
10527
|
+
* import { buildKeycloakCallbacks } from '@digilogiclabs/platform-core'
|
|
10528
|
+
* import Keycloak from 'next-auth/providers/keycloak'
|
|
10529
|
+
*
|
|
10530
|
+
* const callbacks = buildKeycloakCallbacks({
|
|
10531
|
+
* issuer: process.env.AUTH_KEYCLOAK_ISSUER!,
|
|
10532
|
+
* clientId: process.env.AUTH_KEYCLOAK_ID!,
|
|
10533
|
+
* clientSecret: process.env.AUTH_KEYCLOAK_SECRET!,
|
|
10534
|
+
* defaultRoles: ['default-roles-my-realm'],
|
|
10535
|
+
* })
|
|
10536
|
+
*
|
|
10537
|
+
* export const authConfig = {
|
|
10538
|
+
* providers: [Keycloak({ ... })],
|
|
10539
|
+
* session: { strategy: 'jwt' },
|
|
10540
|
+
* callbacks,
|
|
10541
|
+
* }
|
|
10542
|
+
* ```
|
|
10543
|
+
*/
|
|
10544
|
+
interface KeycloakCallbacksConfig {
|
|
10545
|
+
/** Keycloak issuer URL */
|
|
10546
|
+
issuer: string;
|
|
10547
|
+
/** OAuth client ID */
|
|
10548
|
+
clientId: string;
|
|
10549
|
+
/** OAuth client secret */
|
|
10550
|
+
clientSecret: string;
|
|
10551
|
+
/** Realm-specific default roles to filter (e.g. ['default-roles-my-realm']) */
|
|
10552
|
+
defaultRoles?: string[];
|
|
10553
|
+
/** Enable debug logging (default: NODE_ENV === 'development') */
|
|
10554
|
+
debug?: boolean;
|
|
10555
|
+
}
|
|
10556
|
+
/**
|
|
10557
|
+
* Extended JWT token shape used by the Keycloak callbacks.
|
|
10558
|
+
* These fields are added to the Auth.js JWT token during sign-in and refresh.
|
|
10559
|
+
*/
|
|
10560
|
+
interface KeycloakJwtFields {
|
|
10561
|
+
id?: string;
|
|
10562
|
+
accessToken?: string;
|
|
10563
|
+
refreshToken?: string;
|
|
10564
|
+
idToken?: string;
|
|
10565
|
+
accessTokenExpires?: number;
|
|
10566
|
+
roles?: string[];
|
|
10567
|
+
error?: string;
|
|
10568
|
+
}
|
|
10569
|
+
interface AuthCookiesConfig {
|
|
10570
|
+
/** Production cookie domain (e.g. '.digilogiclabs.com'). Omit for default domain. */
|
|
10571
|
+
domain?: string;
|
|
10572
|
+
/** Include session token cookie config (default: true) */
|
|
10573
|
+
sessionToken?: boolean;
|
|
10574
|
+
/** Include callback URL cookie config (default: true) */
|
|
10575
|
+
callbackUrl?: boolean;
|
|
10576
|
+
}
|
|
10577
|
+
/**
|
|
10578
|
+
* Build Auth.js cookie configuration for cross-domain OIDC.
|
|
10579
|
+
*
|
|
10580
|
+
* Handles the common pattern of configuring cookies to work across
|
|
10581
|
+
* www and non-www domains (e.g. digilogiclabs.com and www.digilogiclabs.com).
|
|
10582
|
+
*
|
|
10583
|
+
* PKCE and state cookies are always included for OAuth security.
|
|
10584
|
+
* Session token and callback URL cookies are included by default.
|
|
10585
|
+
*
|
|
10586
|
+
* @example
|
|
10587
|
+
* ```typescript
|
|
10588
|
+
* import { buildAuthCookies } from '@digilogiclabs/platform-core'
|
|
10589
|
+
*
|
|
10590
|
+
* export const authConfig = {
|
|
10591
|
+
* cookies: buildAuthCookies({ domain: '.digilogiclabs.com' }),
|
|
10592
|
+
* // ...
|
|
10593
|
+
* }
|
|
10594
|
+
* ```
|
|
10595
|
+
*/
|
|
10596
|
+
declare function buildAuthCookies(config?: AuthCookiesConfig): Record<string, {
|
|
10597
|
+
name: string;
|
|
10598
|
+
options: {
|
|
10599
|
+
httpOnly: boolean;
|
|
10600
|
+
sameSite: "lax";
|
|
10601
|
+
path: string;
|
|
10602
|
+
secure: boolean;
|
|
10603
|
+
domain: string | undefined;
|
|
10604
|
+
};
|
|
10605
|
+
}>;
|
|
10606
|
+
interface RedirectCallbackConfig {
|
|
10607
|
+
/** Allow www variant redirects (e.g. www.example.com ↔ example.com) */
|
|
10608
|
+
allowWwwVariant?: boolean;
|
|
10609
|
+
}
|
|
10610
|
+
/**
|
|
10611
|
+
* Build a standard Auth.js redirect callback.
|
|
10612
|
+
*
|
|
10613
|
+
* Handles common redirect patterns:
|
|
10614
|
+
* - Relative URLs → prefixed with baseUrl
|
|
10615
|
+
* - Same-origin URLs → allowed
|
|
10616
|
+
* - www variant URLs → optionally allowed
|
|
10617
|
+
* - Everything else → baseUrl
|
|
10618
|
+
*
|
|
10619
|
+
* @example
|
|
10620
|
+
* ```typescript
|
|
10621
|
+
* import { buildRedirectCallback } from '@digilogiclabs/platform-core'
|
|
10622
|
+
*
|
|
10623
|
+
* export const authConfig = {
|
|
10624
|
+
* callbacks: {
|
|
10625
|
+
* redirect: buildRedirectCallback({ allowWwwVariant: true }),
|
|
10626
|
+
* },
|
|
10627
|
+
* }
|
|
10628
|
+
* ```
|
|
10629
|
+
*/
|
|
10630
|
+
declare function buildRedirectCallback(config?: RedirectCallbackConfig): ({ url, baseUrl }: {
|
|
10631
|
+
url: string;
|
|
10632
|
+
baseUrl: string;
|
|
10633
|
+
}) => Promise<string>;
|
|
10634
|
+
/**
|
|
10635
|
+
* Build Auth.js JWT and session callbacks for Keycloak.
|
|
10636
|
+
*
|
|
10637
|
+
* Returns an object with `jwt` and `session` callbacks that handle:
|
|
10638
|
+
* - Storing Keycloak tokens on initial sign-in
|
|
10639
|
+
* - Parsing realm roles from the access token
|
|
10640
|
+
* - Automatic token refresh when expired
|
|
10641
|
+
* - Mapping tokens/roles to the session object
|
|
10642
|
+
*
|
|
10643
|
+
* The callbacks are Edge-runtime compatible.
|
|
10644
|
+
*/
|
|
10645
|
+
declare function buildKeycloakCallbacks(config: KeycloakCallbacksConfig): {
|
|
10646
|
+
/**
|
|
10647
|
+
* JWT callback — stores Keycloak tokens and handles refresh.
|
|
10648
|
+
*
|
|
10649
|
+
* Compatible with Auth.js v5 JWT callback signature.
|
|
10650
|
+
*/
|
|
10651
|
+
jwt({ token, user, account, }: {
|
|
10652
|
+
token: Record<string, unknown>;
|
|
10653
|
+
user?: Record<string, unknown>;
|
|
10654
|
+
account?: Record<string, unknown> | null;
|
|
10655
|
+
}): Promise<Record<string, unknown>>;
|
|
10656
|
+
/**
|
|
10657
|
+
* Session callback — maps JWT fields to the session object.
|
|
10658
|
+
*
|
|
10659
|
+
* Compatible with Auth.js v5 session callback signature.
|
|
10660
|
+
*/
|
|
10661
|
+
session({ session, token, }: {
|
|
10662
|
+
session: Record<string, unknown>;
|
|
10663
|
+
token: Record<string, unknown>;
|
|
10664
|
+
}): Promise<Record<string, unknown>>;
|
|
10665
|
+
};
|
|
10666
|
+
|
|
10667
|
+
/**
|
|
10668
|
+
* API Security Types & Helpers
|
|
10669
|
+
*
|
|
10670
|
+
* Framework-agnostic types and utilities for building composable
|
|
10671
|
+
* API security wrappers. These define the shared contract that
|
|
10672
|
+
* framework-specific implementations (Next.js, Express, .NET) follow.
|
|
10673
|
+
*
|
|
10674
|
+
* The actual wrappers (withPublicApi, withAdminApi, etc.) live in each
|
|
10675
|
+
* app because they depend on framework-specific request/response types.
|
|
10676
|
+
* This module provides the shared types and logic they all use.
|
|
10677
|
+
*/
|
|
10678
|
+
/**
|
|
10679
|
+
* How a request was authenticated.
|
|
10680
|
+
* Used by audit logging and authorization decisions.
|
|
10681
|
+
*/
|
|
10682
|
+
type AuthMethod = "session" | "bearer_token" | "api_key" | "webhook_signature" | "cron_secret" | "none";
|
|
10683
|
+
/**
|
|
10684
|
+
* Audit configuration for a secured route.
|
|
10685
|
+
* Tells the security wrapper what to log.
|
|
10686
|
+
*/
|
|
10687
|
+
interface RouteAuditConfig {
|
|
10688
|
+
/** The action being performed (e.g. 'game.server.create') */
|
|
10689
|
+
action: string;
|
|
10690
|
+
/** The resource type being acted on (e.g. 'game_server') */
|
|
10691
|
+
resourceType: string;
|
|
10692
|
+
}
|
|
10693
|
+
/**
|
|
10694
|
+
* Rate limit preset configuration.
|
|
10695
|
+
* Matches the structure used by all apps.
|
|
10696
|
+
*/
|
|
10697
|
+
interface RateLimitPreset {
|
|
10698
|
+
/** Maximum requests allowed in the window */
|
|
10699
|
+
limit: number;
|
|
10700
|
+
/** Window duration in seconds */
|
|
10701
|
+
windowSeconds: number;
|
|
10702
|
+
/** Higher limit for authenticated users */
|
|
10703
|
+
authenticatedLimit?: number;
|
|
10704
|
+
/** Block duration when limit exceeded (seconds) */
|
|
10705
|
+
blockDurationSeconds?: number;
|
|
10706
|
+
}
|
|
10707
|
+
/**
|
|
10708
|
+
* Standard rate limit presets shared across all apps.
|
|
10709
|
+
*
|
|
10710
|
+
* Apps can extend with their own domain-specific presets:
|
|
10711
|
+
* ```typescript
|
|
10712
|
+
* const APP_RATE_LIMITS = {
|
|
10713
|
+
* ...StandardRateLimitPresets,
|
|
10714
|
+
* gameServerCreate: { limit: 5, windowSeconds: 3600, blockDurationSeconds: 3600 },
|
|
10715
|
+
* }
|
|
10716
|
+
* ```
|
|
10717
|
+
*/
|
|
10718
|
+
declare const StandardRateLimitPresets: {
|
|
10719
|
+
/** General API: 100/min, 200/min authenticated */
|
|
10720
|
+
readonly apiGeneral: {
|
|
10721
|
+
readonly limit: 100;
|
|
10722
|
+
readonly windowSeconds: 60;
|
|
10723
|
+
readonly authenticatedLimit: 200;
|
|
10724
|
+
};
|
|
10725
|
+
/** Admin operations: 100/min (admins are trusted) */
|
|
10726
|
+
readonly adminAction: {
|
|
10727
|
+
readonly limit: 100;
|
|
10728
|
+
readonly windowSeconds: 60;
|
|
10729
|
+
};
|
|
10730
|
+
/** AI/expensive operations: 20/hour, 50/hour authenticated */
|
|
10731
|
+
readonly aiRequest: {
|
|
10732
|
+
readonly limit: 20;
|
|
10733
|
+
readonly windowSeconds: 3600;
|
|
10734
|
+
readonly authenticatedLimit: 50;
|
|
10735
|
+
};
|
|
10736
|
+
/** Auth attempts: 5/15min with 15min block */
|
|
10737
|
+
readonly authAttempt: {
|
|
10738
|
+
readonly limit: 5;
|
|
10739
|
+
readonly windowSeconds: 900;
|
|
10740
|
+
readonly blockDurationSeconds: 900;
|
|
10741
|
+
};
|
|
10742
|
+
/** Contact/public forms: 10/hour */
|
|
10743
|
+
readonly publicForm: {
|
|
10744
|
+
readonly limit: 10;
|
|
10745
|
+
readonly windowSeconds: 3600;
|
|
10746
|
+
readonly blockDurationSeconds: 1800;
|
|
10747
|
+
};
|
|
10748
|
+
/** Checkout/billing: 10/hour with 1hr block */
|
|
10749
|
+
readonly checkout: {
|
|
10750
|
+
readonly limit: 10;
|
|
10751
|
+
readonly windowSeconds: 3600;
|
|
10752
|
+
readonly blockDurationSeconds: 3600;
|
|
10753
|
+
};
|
|
10754
|
+
};
|
|
10755
|
+
/**
|
|
10756
|
+
* Configuration for a secured API handler.
|
|
10757
|
+
*
|
|
10758
|
+
* This is the framework-agnostic config shape. Each framework's
|
|
10759
|
+
* wrapper (withPublicApi, withAdminApi, etc.) maps to this structure.
|
|
10760
|
+
*/
|
|
10761
|
+
interface ApiSecurityConfig {
|
|
10762
|
+
/** Whether authentication is required */
|
|
10763
|
+
requireAuth: boolean;
|
|
10764
|
+
/** Whether admin role is required */
|
|
10765
|
+
requireAdmin: boolean;
|
|
10766
|
+
/** Required roles (user must have at least one) */
|
|
10767
|
+
requireRoles?: string[];
|
|
10768
|
+
/** Allow legacy bearer token as alternative to session auth */
|
|
10769
|
+
allowBearerToken?: boolean;
|
|
10770
|
+
/** Rate limit preset name or custom config */
|
|
10771
|
+
rateLimit?: string | RateLimitPreset;
|
|
10772
|
+
/** Audit logging config */
|
|
10773
|
+
audit?: RouteAuditConfig;
|
|
10774
|
+
/** Human-readable operation name for logging */
|
|
10775
|
+
operation?: string;
|
|
10776
|
+
/** Skip rate limiting */
|
|
10777
|
+
skipRateLimit?: boolean;
|
|
10778
|
+
/** Skip audit logging */
|
|
10779
|
+
skipAudit?: boolean;
|
|
10780
|
+
}
|
|
10781
|
+
/**
|
|
10782
|
+
* Minimal session shape that all auth systems provide.
|
|
10783
|
+
* Maps to Auth.js Session, .NET ClaimsPrincipal, etc.
|
|
10784
|
+
*/
|
|
10785
|
+
interface SecuritySession {
|
|
10786
|
+
user: {
|
|
10787
|
+
id: string;
|
|
10788
|
+
email?: string | null;
|
|
10789
|
+
name?: string | null;
|
|
10790
|
+
roles?: string[];
|
|
10791
|
+
};
|
|
10792
|
+
}
|
|
10793
|
+
/**
|
|
10794
|
+
* Context available to secured route handlers after all security
|
|
10795
|
+
* checks have passed. Framework wrappers extend this with their
|
|
10796
|
+
* own fields (e.g. NextRequest, validated body, etc.).
|
|
10797
|
+
*/
|
|
10798
|
+
interface ApiSecurityContext {
|
|
10799
|
+
/** Authenticated session (null for public routes or token auth) */
|
|
10800
|
+
session: SecuritySession | null;
|
|
10801
|
+
/** How the request was authenticated */
|
|
10802
|
+
authMethod: AuthMethod;
|
|
10803
|
+
/** Whether the user has admin privileges */
|
|
10804
|
+
isAdmin: boolean;
|
|
10805
|
+
/** Request correlation ID */
|
|
10806
|
+
requestId: string;
|
|
10807
|
+
}
|
|
10808
|
+
/**
|
|
10809
|
+
* Determine the appropriate rate limit key for a request.
|
|
10810
|
+
*
|
|
10811
|
+
* Priority: user ID > email > IP address.
|
|
10812
|
+
* Authenticated users get their own bucket (and potentially higher limits).
|
|
10813
|
+
*
|
|
10814
|
+
* @param session - Current session (if any)
|
|
10815
|
+
* @param clientIp - Client IP address
|
|
10816
|
+
* @returns { identifier, isAuthenticated }
|
|
10817
|
+
*/
|
|
10818
|
+
declare function resolveRateLimitIdentifier(session: SecuritySession | null, clientIp: string): {
|
|
10819
|
+
identifier: string;
|
|
10820
|
+
isAuthenticated: boolean;
|
|
10821
|
+
};
|
|
10822
|
+
/**
|
|
10823
|
+
* Extract the client IP from standard proxy headers.
|
|
10824
|
+
*
|
|
10825
|
+
* Checks (in order): CF-Connecting-IP, X-Real-IP, X-Forwarded-For.
|
|
10826
|
+
* Use this to ensure consistent IP extraction across all apps.
|
|
10827
|
+
*
|
|
10828
|
+
* @param getHeader - Header getter function
|
|
10829
|
+
* @returns Client IP or 'unknown'
|
|
10830
|
+
*/
|
|
10831
|
+
declare function extractClientIp(getHeader: (name: string) => string | null | undefined): string;
|
|
10832
|
+
/**
|
|
10833
|
+
* Build the standard rate limit response headers.
|
|
10834
|
+
*
|
|
10835
|
+
* @returns Headers object with X-RateLimit-* headers
|
|
10836
|
+
*/
|
|
10837
|
+
declare function buildRateLimitHeaders(limit: number, remaining: number, resetAtMs: number): Record<string, string>;
|
|
10838
|
+
/**
|
|
10839
|
+
* Build a standard error response body.
|
|
10840
|
+
* Ensures consistent error shape across all apps.
|
|
10841
|
+
*/
|
|
10842
|
+
declare function buildErrorBody(error: string, extra?: Record<string, unknown>): Record<string, unknown>;
|
|
10843
|
+
/**
|
|
10844
|
+
* Pre-built security configurations for common route types.
|
|
10845
|
+
*
|
|
10846
|
+
* Use these as the base for framework-specific wrappers:
|
|
10847
|
+
* ```typescript
|
|
10848
|
+
* // In your app's api-security.ts
|
|
10849
|
+
* export function withPublicApi(config, handler) {
|
|
10850
|
+
* return createSecureHandler({
|
|
10851
|
+
* ...WrapperPresets.public,
|
|
10852
|
+
* ...config,
|
|
10853
|
+
* }, handler)
|
|
10854
|
+
* }
|
|
10855
|
+
* ```
|
|
10856
|
+
*/
|
|
10857
|
+
declare const WrapperPresets: {
|
|
10858
|
+
/** Public route: no auth, rate limited */
|
|
10859
|
+
readonly public: {
|
|
10860
|
+
readonly requireAuth: false;
|
|
10861
|
+
readonly requireAdmin: false;
|
|
10862
|
+
readonly rateLimit: "apiGeneral";
|
|
10863
|
+
};
|
|
10864
|
+
/** Authenticated route: requires session */
|
|
10865
|
+
readonly authenticated: {
|
|
10866
|
+
readonly requireAuth: true;
|
|
10867
|
+
readonly requireAdmin: false;
|
|
10868
|
+
readonly rateLimit: "apiGeneral";
|
|
10869
|
+
};
|
|
10870
|
+
/** Admin route: requires session with admin role */
|
|
10871
|
+
readonly admin: {
|
|
10872
|
+
readonly requireAuth: true;
|
|
10873
|
+
readonly requireAdmin: true;
|
|
10874
|
+
readonly rateLimit: "adminAction";
|
|
10875
|
+
};
|
|
10876
|
+
/** Legacy admin: accepts session OR bearer token */
|
|
10877
|
+
readonly legacyAdmin: {
|
|
10878
|
+
readonly requireAuth: true;
|
|
10879
|
+
readonly requireAdmin: true;
|
|
10880
|
+
readonly allowBearerToken: true;
|
|
10881
|
+
readonly rateLimit: "adminAction";
|
|
10882
|
+
};
|
|
10883
|
+
/** AI/expensive: requires auth, strict rate limit */
|
|
10884
|
+
readonly ai: {
|
|
10885
|
+
readonly requireAuth: true;
|
|
10886
|
+
readonly requireAdmin: false;
|
|
10887
|
+
readonly rateLimit: "aiRequest";
|
|
10888
|
+
};
|
|
10889
|
+
/** Cron: no rate limit, admin-level access */
|
|
10890
|
+
readonly cron: {
|
|
10891
|
+
readonly requireAuth: true;
|
|
10892
|
+
readonly requireAdmin: false;
|
|
10893
|
+
readonly skipRateLimit: true;
|
|
10894
|
+
readonly skipAudit: false;
|
|
10895
|
+
};
|
|
10896
|
+
};
|
|
10897
|
+
|
|
10898
|
+
/**
|
|
10899
|
+
* Common Validation Schemas
|
|
10900
|
+
*
|
|
10901
|
+
* Reusable Zod schemas for request validation across all apps.
|
|
10902
|
+
* These are the building blocks — apps compose them into
|
|
10903
|
+
* route-specific schemas for their own domain logic.
|
|
10904
|
+
*
|
|
10905
|
+
* Requires `zod` as a peer dependency (already in platform-core).
|
|
10906
|
+
*/
|
|
10907
|
+
|
|
10908
|
+
/** Validated, normalized email address */
|
|
10909
|
+
declare const EmailSchema: z.ZodString;
|
|
10910
|
+
/** Password with minimum security requirements */
|
|
10911
|
+
declare const PasswordSchema: z.ZodString;
|
|
10912
|
+
/** URL-safe slug (lowercase alphanumeric + hyphens) */
|
|
10913
|
+
declare const SlugSchema: z.ZodString;
|
|
10914
|
+
/** Phone number (international format, flexible) */
|
|
10915
|
+
declare const PhoneSchema: z.ZodString;
|
|
10916
|
+
/** Human name (letters, spaces, hyphens, apostrophes) */
|
|
10917
|
+
declare const PersonNameSchema: z.ZodString;
|
|
10918
|
+
/**
|
|
10919
|
+
* Create a text schema that blocks HTML tags and links.
|
|
10920
|
+
* Use for user-facing text fields (contact forms, comments, etc.)
|
|
10921
|
+
*
|
|
10922
|
+
* @param options - Customize min/max length and error messages
|
|
10923
|
+
*
|
|
10924
|
+
* @example
|
|
10925
|
+
* ```typescript
|
|
10926
|
+
* const MessageSchema = createSafeTextSchema({ min: 10, max: 1000 })
|
|
10927
|
+
* const CommentSchema = createSafeTextSchema({ max: 500, allowUrls: true })
|
|
10928
|
+
* ```
|
|
10929
|
+
*/
|
|
10930
|
+
declare function createSafeTextSchema(options?: {
|
|
10931
|
+
min?: number;
|
|
10932
|
+
max?: number;
|
|
10933
|
+
allowHtml?: boolean;
|
|
10934
|
+
allowUrls?: boolean;
|
|
10935
|
+
fieldName?: string;
|
|
10936
|
+
}): z.ZodType<string, z.ZodTypeDef, string>;
|
|
10937
|
+
/** Standard pagination query parameters */
|
|
10938
|
+
declare const PaginationSchema: z.ZodObject<{
|
|
10939
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
10940
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
10941
|
+
sortBy: z.ZodOptional<z.ZodString>;
|
|
10942
|
+
sortOrder: z.ZodDefault<z.ZodEnum<["asc", "desc"]>>;
|
|
10943
|
+
}, "strip", z.ZodTypeAny, {
|
|
10944
|
+
limit: number;
|
|
10945
|
+
page: number;
|
|
10946
|
+
sortOrder: "asc" | "desc";
|
|
10947
|
+
sortBy?: string | undefined;
|
|
10948
|
+
}, {
|
|
10949
|
+
sortBy?: string | undefined;
|
|
10950
|
+
limit?: number | undefined;
|
|
10951
|
+
page?: number | undefined;
|
|
10952
|
+
sortOrder?: "asc" | "desc" | undefined;
|
|
10953
|
+
}>;
|
|
10954
|
+
/** Date range filter (ISO 8601 datetime strings) */
|
|
10955
|
+
declare const DateRangeSchema: z.ZodEffects<z.ZodObject<{
|
|
10956
|
+
startDate: z.ZodString;
|
|
10957
|
+
endDate: z.ZodString;
|
|
10958
|
+
}, "strip", z.ZodTypeAny, {
|
|
10959
|
+
startDate: string;
|
|
10960
|
+
endDate: string;
|
|
10961
|
+
}, {
|
|
10962
|
+
startDate: string;
|
|
10963
|
+
endDate: string;
|
|
10964
|
+
}>, {
|
|
10965
|
+
startDate: string;
|
|
10966
|
+
endDate: string;
|
|
10967
|
+
}, {
|
|
10968
|
+
startDate: string;
|
|
10969
|
+
endDate: string;
|
|
10970
|
+
}>;
|
|
10971
|
+
/** Search query with optional filters */
|
|
10972
|
+
declare const SearchQuerySchema: z.ZodObject<{
|
|
10973
|
+
query: z.ZodString;
|
|
10974
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
10975
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
10976
|
+
}, "strip", z.ZodTypeAny, {
|
|
10977
|
+
query: string;
|
|
10978
|
+
limit: number;
|
|
10979
|
+
page: number;
|
|
10980
|
+
}, {
|
|
10981
|
+
query: string;
|
|
10982
|
+
limit?: number | undefined;
|
|
10983
|
+
page?: number | undefined;
|
|
10984
|
+
}>;
|
|
10985
|
+
/** Login credentials */
|
|
10986
|
+
declare const LoginSchema: z.ZodObject<{
|
|
10987
|
+
email: z.ZodString;
|
|
10988
|
+
password: z.ZodString;
|
|
10989
|
+
}, "strip", z.ZodTypeAny, {
|
|
10990
|
+
email: string;
|
|
10991
|
+
password: string;
|
|
10992
|
+
}, {
|
|
10993
|
+
email: string;
|
|
10994
|
+
password: string;
|
|
10995
|
+
}>;
|
|
10996
|
+
/** Signup with optional name */
|
|
10997
|
+
declare const SignupSchema: z.ZodObject<{
|
|
10998
|
+
email: z.ZodString;
|
|
10999
|
+
password: z.ZodString;
|
|
11000
|
+
name: z.ZodOptional<z.ZodString>;
|
|
11001
|
+
}, "strip", z.ZodTypeAny, {
|
|
11002
|
+
email: string;
|
|
11003
|
+
password: string;
|
|
11004
|
+
name?: string | undefined;
|
|
11005
|
+
}, {
|
|
11006
|
+
email: string;
|
|
11007
|
+
password: string;
|
|
11008
|
+
name?: string | undefined;
|
|
11009
|
+
}>;
|
|
11010
|
+
type EmailInput = z.infer<typeof EmailSchema>;
|
|
11011
|
+
type PaginationInput = z.infer<typeof PaginationSchema>;
|
|
11012
|
+
type DateRangeInput = z.infer<typeof DateRangeSchema>;
|
|
11013
|
+
type SearchQueryInput = z.infer<typeof SearchQuerySchema>;
|
|
11014
|
+
type LoginInput = z.infer<typeof LoginSchema>;
|
|
11015
|
+
type SignupInput = z.infer<typeof SignupSchema>;
|
|
11016
|
+
|
|
11017
|
+
/**
|
|
11018
|
+
* Feature Flag System
|
|
11019
|
+
*
|
|
11020
|
+
* Generic, type-safe feature flag builder for staged rollout.
|
|
11021
|
+
* Each app defines its own flags; this module provides the
|
|
11022
|
+
* infrastructure for evaluating them by environment.
|
|
11023
|
+
*
|
|
11024
|
+
* @example
|
|
11025
|
+
* ```typescript
|
|
11026
|
+
* // Define your app's flags
|
|
11027
|
+
* const flags = createFeatureFlags({
|
|
11028
|
+
* STRIPE_PAYMENTS: {
|
|
11029
|
+
* development: true,
|
|
11030
|
+
* staging: true,
|
|
11031
|
+
* production: { envVar: 'ENABLE_PAYMENTS' },
|
|
11032
|
+
* },
|
|
11033
|
+
* PUBLIC_SIGNUP: {
|
|
11034
|
+
* development: true,
|
|
11035
|
+
* staging: false,
|
|
11036
|
+
* production: { envVar: 'ENABLE_PUBLIC_SIGNUP' },
|
|
11037
|
+
* },
|
|
11038
|
+
* AI_FEATURES: {
|
|
11039
|
+
* development: true,
|
|
11040
|
+
* staging: { envVar: 'ENABLE_AI' },
|
|
11041
|
+
* production: false,
|
|
11042
|
+
* },
|
|
11043
|
+
* })
|
|
11044
|
+
*
|
|
11045
|
+
* // Evaluate at runtime
|
|
11046
|
+
* const resolved = flags.resolve() // reads NODE_ENV + DEPLOYMENT_STAGE
|
|
11047
|
+
* if (resolved.STRIPE_PAYMENTS) { ... }
|
|
11048
|
+
*
|
|
11049
|
+
* // Check a single flag
|
|
11050
|
+
* if (flags.isEnabled('AI_FEATURES')) { ... }
|
|
11051
|
+
* ```
|
|
11052
|
+
*/
|
|
11053
|
+
type DeploymentStage = "development" | "staging" | "preview" | "production";
|
|
11054
|
+
/**
|
|
11055
|
+
* How a flag is resolved in a given environment.
|
|
11056
|
+
* - `true` / `false` — hardcoded on/off
|
|
11057
|
+
* - `{ envVar: string }` — read from environment variable (truthy = "true")
|
|
11058
|
+
* - `{ envVar: string, default: boolean }` — with fallback
|
|
11059
|
+
*/
|
|
11060
|
+
type FlagValue = boolean | {
|
|
11061
|
+
envVar: string;
|
|
11062
|
+
default?: boolean;
|
|
11063
|
+
};
|
|
11064
|
+
/**
|
|
11065
|
+
* Flag definition across deployment stages.
|
|
11066
|
+
*/
|
|
11067
|
+
interface FlagDefinition {
|
|
11068
|
+
development: FlagValue;
|
|
11069
|
+
staging: FlagValue;
|
|
11070
|
+
production: FlagValue;
|
|
11071
|
+
}
|
|
11072
|
+
/**
|
|
11073
|
+
* Map of flag name to definition.
|
|
11074
|
+
*/
|
|
11075
|
+
type FlagDefinitions<T extends string = string> = Record<T, FlagDefinition>;
|
|
11076
|
+
/**
|
|
11077
|
+
* Resolved flags — all booleans.
|
|
11078
|
+
*/
|
|
11079
|
+
type ResolvedFlags<T extends string = string> = Record<T, boolean>;
|
|
11080
|
+
/**
|
|
11081
|
+
* Allowlist configuration for tester-gated access.
|
|
11082
|
+
*/
|
|
11083
|
+
interface AllowlistConfig {
|
|
11084
|
+
/** Environment variable containing comma-separated emails */
|
|
11085
|
+
envVar?: string;
|
|
11086
|
+
/** Hardcoded fallback emails */
|
|
11087
|
+
fallback?: string[];
|
|
11088
|
+
}
|
|
11089
|
+
/**
|
|
11090
|
+
* Detect the current deployment stage from environment variables.
|
|
11091
|
+
*/
|
|
11092
|
+
declare function detectStage(): DeploymentStage;
|
|
11093
|
+
/**
|
|
11094
|
+
* Create a type-safe feature flag system.
|
|
11095
|
+
*
|
|
11096
|
+
* @param definitions - Flag definitions per environment
|
|
11097
|
+
* @returns Feature flag accessor with resolve() and isEnabled()
|
|
11098
|
+
*/
|
|
11099
|
+
declare function createFeatureFlags<T extends string>(definitions: FlagDefinitions<T>): {
|
|
11100
|
+
/**
|
|
11101
|
+
* Resolve all flags for the current environment.
|
|
11102
|
+
* Call this once at startup or per-request for dynamic flags.
|
|
11103
|
+
*/
|
|
11104
|
+
resolve(stage?: DeploymentStage): ResolvedFlags<T>;
|
|
11105
|
+
/**
|
|
11106
|
+
* Check if a single flag is enabled.
|
|
11107
|
+
*/
|
|
11108
|
+
isEnabled(flag: T, stage?: DeploymentStage): boolean;
|
|
11109
|
+
/**
|
|
11110
|
+
* Get the flag definitions (for introspection/admin UI).
|
|
11111
|
+
*/
|
|
11112
|
+
definitions: FlagDefinitions<T>;
|
|
11113
|
+
};
|
|
11114
|
+
/**
|
|
11115
|
+
* Build an allowlist from environment variable + fallback emails.
|
|
11116
|
+
*
|
|
11117
|
+
* @example
|
|
11118
|
+
* ```typescript
|
|
11119
|
+
* const testers = buildAllowlist({
|
|
11120
|
+
* envVar: 'ADMIN_EMAILS',
|
|
11121
|
+
* fallback: ['admin@example.com'],
|
|
11122
|
+
* })
|
|
11123
|
+
* if (testers.includes(userEmail)) { ... }
|
|
11124
|
+
* ```
|
|
11125
|
+
*/
|
|
11126
|
+
declare function buildAllowlist(config: AllowlistConfig): string[];
|
|
11127
|
+
/**
|
|
11128
|
+
* Check if an email is in the allowlist (case-insensitive).
|
|
11129
|
+
*/
|
|
11130
|
+
declare function isAllowlisted(email: string, allowlist: string[]): boolean;
|
|
11131
|
+
|
|
11132
|
+
/**
|
|
11133
|
+
* Standalone Rate Limiter
|
|
11134
|
+
*
|
|
11135
|
+
* Framework-agnostic sliding window rate limiter that works with
|
|
11136
|
+
* any storage backend (Redis, memory, etc.). Apps provide a storage
|
|
11137
|
+
* adapter; this module handles the algorithm and types.
|
|
11138
|
+
*
|
|
11139
|
+
* @example
|
|
11140
|
+
* ```typescript
|
|
11141
|
+
* import {
|
|
11142
|
+
* checkRateLimit,
|
|
11143
|
+
* createMemoryRateLimitStore,
|
|
11144
|
+
* CommonRateLimits,
|
|
11145
|
+
* } from '@digilogiclabs/platform-core'
|
|
11146
|
+
*
|
|
11147
|
+
* const store = createMemoryRateLimitStore()
|
|
11148
|
+
*
|
|
11149
|
+
* const result = await checkRateLimit('api-call', 'user:123', CommonRateLimits.apiGeneral, { store })
|
|
11150
|
+
* if (!result.allowed) {
|
|
11151
|
+
* // Return 429 with result.retryAfterSeconds
|
|
11152
|
+
* }
|
|
11153
|
+
* ```
|
|
11154
|
+
*/
|
|
11155
|
+
/** Configuration for a rate limit rule */
|
|
11156
|
+
interface RateLimitRule {
|
|
11157
|
+
/** Maximum requests allowed in the window */
|
|
11158
|
+
limit: number;
|
|
11159
|
+
/** Time window in seconds */
|
|
11160
|
+
windowSeconds: number;
|
|
11161
|
+
/** Different limit for authenticated users (optional) */
|
|
11162
|
+
authenticatedLimit?: number;
|
|
11163
|
+
/** Block duration in seconds when limit is exceeded (optional) */
|
|
11164
|
+
blockDurationSeconds?: number;
|
|
11165
|
+
}
|
|
11166
|
+
/** Result of a rate limit check */
|
|
11167
|
+
interface RateLimitCheckResult {
|
|
11168
|
+
/** Whether the request is allowed */
|
|
11169
|
+
allowed: boolean;
|
|
11170
|
+
/** Remaining requests in the current window */
|
|
11171
|
+
remaining: number;
|
|
11172
|
+
/** Unix timestamp (ms) when the window resets */
|
|
11173
|
+
resetAt: number;
|
|
11174
|
+
/** Current request count in the window */
|
|
11175
|
+
current: number;
|
|
11176
|
+
/** The limit that was applied */
|
|
11177
|
+
limit: number;
|
|
11178
|
+
/** Seconds until retry is allowed (for 429 Retry-After header) */
|
|
11179
|
+
retryAfterSeconds: number;
|
|
11180
|
+
}
|
|
11181
|
+
/**
|
|
11182
|
+
* Storage backend for rate limiting.
|
|
11183
|
+
*
|
|
11184
|
+
* Implementations should support sorted-set-like semantics for
|
|
11185
|
+
* accurate sliding window rate limiting.
|
|
11186
|
+
*/
|
|
11187
|
+
interface RateLimitStore {
|
|
11188
|
+
/**
|
|
11189
|
+
* Add an entry to the sliding window and return the current count.
|
|
11190
|
+
* Should atomically: remove entries older than windowStart,
|
|
11191
|
+
* add the new entry, and return the total count.
|
|
11192
|
+
*/
|
|
11193
|
+
increment(key: string, windowMs: number, now: number): Promise<{
|
|
11194
|
+
count: number;
|
|
11195
|
+
}>;
|
|
11196
|
+
/** Check if a key is blocked and return remaining TTL */
|
|
11197
|
+
isBlocked(key: string): Promise<{
|
|
11198
|
+
blocked: boolean;
|
|
11199
|
+
ttlMs: number;
|
|
11200
|
+
}>;
|
|
11201
|
+
/** Set a temporary block on a key */
|
|
11202
|
+
setBlock(key: string, durationSeconds: number): Promise<void>;
|
|
11203
|
+
/** Remove all entries for a key (for reset/testing) */
|
|
11204
|
+
reset(key: string): Promise<void>;
|
|
11205
|
+
}
|
|
11206
|
+
/** Options for checkRateLimit */
|
|
11207
|
+
interface RateLimitOptions {
|
|
11208
|
+
/** Storage backend (defaults to in-memory if not provided) */
|
|
11209
|
+
store?: RateLimitStore;
|
|
11210
|
+
/** Whether the user is authenticated (uses authenticatedLimit if available) */
|
|
11211
|
+
isAuthenticated?: boolean;
|
|
11212
|
+
/** Logger for warnings/errors (optional) */
|
|
11213
|
+
logger?: {
|
|
11214
|
+
warn: (msg: string, meta?: Record<string, unknown>) => void;
|
|
11215
|
+
error: (msg: string, meta?: Record<string, unknown>) => void;
|
|
11216
|
+
};
|
|
11217
|
+
}
|
|
11218
|
+
/**
|
|
11219
|
+
* Common rate limit rules for typical operations.
|
|
11220
|
+
* Apps can extend with domain-specific presets.
|
|
11221
|
+
*
|
|
11222
|
+
* @example
|
|
11223
|
+
* ```typescript
|
|
11224
|
+
* const APP_LIMITS = {
|
|
11225
|
+
* ...CommonRateLimits,
|
|
11226
|
+
* serverCreate: { limit: 5, windowSeconds: 3600, blockDurationSeconds: 3600 },
|
|
11227
|
+
* }
|
|
11228
|
+
* ```
|
|
11229
|
+
*/
|
|
11230
|
+
declare const CommonRateLimits: {
|
|
11231
|
+
/** General API: 100/min, 200/min authenticated */
|
|
11232
|
+
readonly apiGeneral: {
|
|
11233
|
+
readonly limit: 100;
|
|
11234
|
+
readonly windowSeconds: 60;
|
|
11235
|
+
readonly authenticatedLimit: 200;
|
|
11236
|
+
};
|
|
11237
|
+
/** Admin actions: 100/min */
|
|
11238
|
+
readonly adminAction: {
|
|
11239
|
+
readonly limit: 100;
|
|
11240
|
+
readonly windowSeconds: 60;
|
|
11241
|
+
};
|
|
11242
|
+
/** Auth attempts: 10/15min with 30min block */
|
|
11243
|
+
readonly authAttempt: {
|
|
11244
|
+
readonly limit: 10;
|
|
11245
|
+
readonly windowSeconds: 900;
|
|
11246
|
+
readonly blockDurationSeconds: 1800;
|
|
11247
|
+
};
|
|
11248
|
+
/** AI/expensive requests: 20/hour, 50/hour authenticated */
|
|
11249
|
+
readonly aiRequest: {
|
|
11250
|
+
readonly limit: 20;
|
|
11251
|
+
readonly windowSeconds: 3600;
|
|
11252
|
+
readonly authenticatedLimit: 50;
|
|
11253
|
+
};
|
|
11254
|
+
/** Public form submissions: 5/hour with 1hr block */
|
|
11255
|
+
readonly publicForm: {
|
|
11256
|
+
readonly limit: 5;
|
|
11257
|
+
readonly windowSeconds: 3600;
|
|
11258
|
+
readonly blockDurationSeconds: 3600;
|
|
11259
|
+
};
|
|
11260
|
+
/** Checkout/billing: 10/hour with 1hr block */
|
|
11261
|
+
readonly checkout: {
|
|
11262
|
+
readonly limit: 10;
|
|
11263
|
+
readonly windowSeconds: 3600;
|
|
11264
|
+
readonly blockDurationSeconds: 3600;
|
|
11265
|
+
};
|
|
11266
|
+
};
|
|
11267
|
+
/**
|
|
11268
|
+
* In-memory rate limit store for testing and graceful degradation.
|
|
11269
|
+
* Not suitable for multi-process or distributed environments.
|
|
11270
|
+
*/
|
|
11271
|
+
declare function createMemoryRateLimitStore(): RateLimitStore;
|
|
11272
|
+
/**
|
|
11273
|
+
* Check rate limit for an operation.
|
|
11274
|
+
*
|
|
11275
|
+
* @param operation - Name of the operation (e.g., 'server-create', 'api-call')
|
|
11276
|
+
* @param identifier - Who is making the request (e.g., 'user:123', 'ip:1.2.3.4')
|
|
11277
|
+
* @param rule - Rate limit configuration
|
|
11278
|
+
* @param options - Storage, auth status, logger
|
|
11279
|
+
* @returns Rate limit check result
|
|
11280
|
+
*/
|
|
11281
|
+
declare function checkRateLimit(operation: string, identifier: string, rule: RateLimitRule, options?: RateLimitOptions): Promise<RateLimitCheckResult>;
|
|
11282
|
+
/**
|
|
11283
|
+
* Get current rate limit status without incrementing the counter.
|
|
11284
|
+
*/
|
|
11285
|
+
declare function getRateLimitStatus(operation: string, identifier: string, rule: RateLimitRule, store?: RateLimitStore): Promise<RateLimitCheckResult | null>;
|
|
11286
|
+
/**
|
|
11287
|
+
* Reset rate limit for an identifier (for admin/testing).
|
|
11288
|
+
*/
|
|
11289
|
+
declare function resetRateLimitForKey(operation: string, identifier: string, store?: RateLimitStore): Promise<void>;
|
|
11290
|
+
/**
|
|
11291
|
+
* Build standard rate limit headers for HTTP responses.
|
|
11292
|
+
*/
|
|
11293
|
+
declare function buildRateLimitResponseHeaders(result: RateLimitCheckResult): Record<string, string>;
|
|
11294
|
+
/**
|
|
11295
|
+
* Resolve a rate limit identifier from a request-like context.
|
|
11296
|
+
* Prefers user ID > email > IP for most accurate limiting.
|
|
11297
|
+
*/
|
|
11298
|
+
declare function resolveIdentifier(session: {
|
|
11299
|
+
user?: {
|
|
11300
|
+
id?: string;
|
|
11301
|
+
email?: string;
|
|
11302
|
+
};
|
|
11303
|
+
} | null | undefined, clientIp?: string): {
|
|
11304
|
+
identifier: string;
|
|
11305
|
+
isAuthenticated: boolean;
|
|
11306
|
+
};
|
|
11307
|
+
|
|
11308
|
+
/**
|
|
11309
|
+
* Audit Logging System
|
|
11310
|
+
*
|
|
11311
|
+
* Framework-agnostic audit logging for security-sensitive operations.
|
|
11312
|
+
* Provides structured audit events with actor, action, resource, and
|
|
11313
|
+
* outcome tracking. Apps provide their own persistence (Redis, DB, etc.)
|
|
11314
|
+
* via a simple callback; this module handles the event model and helpers.
|
|
11315
|
+
*
|
|
11316
|
+
* @example
|
|
11317
|
+
* ```typescript
|
|
11318
|
+
* import { createAuditLogger, StandardAuditActions } from '@digilogiclabs/platform-core'
|
|
11319
|
+
*
|
|
11320
|
+
* const audit = createAuditLogger({
|
|
11321
|
+
* persist: async (record) => {
|
|
11322
|
+
* await redis.setex(`audit:${record.id}`, 90 * 86400, JSON.stringify(record))
|
|
11323
|
+
* },
|
|
11324
|
+
* })
|
|
11325
|
+
*
|
|
11326
|
+
* await audit.log({
|
|
11327
|
+
* actor: { id: userId, email, type: 'user' },
|
|
11328
|
+
* action: StandardAuditActions.LOGIN_SUCCESS,
|
|
11329
|
+
* outcome: 'success',
|
|
11330
|
+
* })
|
|
11331
|
+
* ```
|
|
11332
|
+
*/
|
|
11333
|
+
/** Who performed the action */
|
|
11334
|
+
interface OpsAuditActor {
|
|
11335
|
+
id: string;
|
|
11336
|
+
email?: string;
|
|
11337
|
+
type: "user" | "admin" | "system" | "api_key" | "anonymous";
|
|
11338
|
+
sessionId?: string;
|
|
11339
|
+
}
|
|
11340
|
+
/** What resource was affected */
|
|
11341
|
+
interface OpsAuditResource {
|
|
11342
|
+
type: string;
|
|
11343
|
+
id: string;
|
|
11344
|
+
name?: string;
|
|
11345
|
+
}
|
|
11346
|
+
/** The audit event to log */
|
|
11347
|
+
interface OpsAuditEvent {
|
|
11348
|
+
actor: OpsAuditActor;
|
|
11349
|
+
action: string;
|
|
11350
|
+
resource?: OpsAuditResource;
|
|
11351
|
+
outcome: "success" | "failure" | "blocked" | "pending";
|
|
11352
|
+
metadata?: Record<string, unknown>;
|
|
11353
|
+
reason?: string;
|
|
11354
|
+
}
|
|
11355
|
+
/** Complete audit record with context */
|
|
11356
|
+
interface OpsAuditRecord extends OpsAuditEvent {
|
|
11357
|
+
id: string;
|
|
11358
|
+
timestamp: string;
|
|
11359
|
+
ip?: string;
|
|
11360
|
+
userAgent?: string;
|
|
11361
|
+
requestId?: string;
|
|
11362
|
+
duration?: number;
|
|
11363
|
+
}
|
|
11364
|
+
/** Options for creating an audit logger */
|
|
11365
|
+
interface OpsAuditLoggerOptions {
|
|
10177
11366
|
/**
|
|
10178
|
-
*
|
|
11367
|
+
* Persist an audit record to storage (Redis, DB, etc.).
|
|
11368
|
+
* Called after console logging. Errors are caught and logged,
|
|
11369
|
+
* never thrown — audit failures must not break operations.
|
|
10179
11370
|
*/
|
|
10180
|
-
|
|
11371
|
+
persist?: (record: OpsAuditRecord) => Promise<void>;
|
|
10181
11372
|
/**
|
|
10182
|
-
*
|
|
11373
|
+
* Console logger for structured output.
|
|
11374
|
+
* Defaults to console.log/console.warn.
|
|
10183
11375
|
*/
|
|
10184
|
-
|
|
10185
|
-
|
|
10186
|
-
|
|
11376
|
+
logger?: {
|
|
11377
|
+
info: (msg: string, meta?: Record<string, unknown>) => void;
|
|
11378
|
+
warn: (msg: string, meta?: Record<string, unknown>) => void;
|
|
11379
|
+
error: (msg: string, meta?: Record<string, unknown>) => void;
|
|
11380
|
+
};
|
|
11381
|
+
}
|
|
11382
|
+
/** Request-like object for extracting IP, user agent, request ID */
|
|
11383
|
+
interface AuditRequest {
|
|
11384
|
+
headers: {
|
|
11385
|
+
get(name: string): string | null;
|
|
11386
|
+
};
|
|
11387
|
+
}
|
|
10187
11388
|
/**
|
|
10188
|
-
*
|
|
11389
|
+
* Standard audit action constants.
|
|
11390
|
+
* Apps should extend with domain-specific actions:
|
|
10189
11391
|
*
|
|
10190
|
-
*
|
|
10191
|
-
*
|
|
11392
|
+
* @example
|
|
11393
|
+
* ```typescript
|
|
11394
|
+
* const AppAuditActions = {
|
|
11395
|
+
* ...StandardAuditActions,
|
|
11396
|
+
* SERVER_CREATE: 'game.server.create',
|
|
11397
|
+
* SERVER_DELETE: 'game.server.delete',
|
|
11398
|
+
* } as const
|
|
11399
|
+
* ```
|
|
10192
11400
|
*/
|
|
10193
|
-
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
11401
|
+
declare const StandardAuditActions: {
|
|
11402
|
+
readonly LOGIN_SUCCESS: "auth.login.success";
|
|
11403
|
+
readonly LOGIN_FAILURE: "auth.login.failure";
|
|
11404
|
+
readonly LOGOUT: "auth.logout";
|
|
11405
|
+
readonly SESSION_REFRESH: "auth.session.refresh";
|
|
11406
|
+
readonly PASSWORD_CHANGE: "auth.password.change";
|
|
11407
|
+
readonly PASSWORD_RESET: "auth.password.reset";
|
|
11408
|
+
readonly CHECKOUT_START: "billing.checkout.start";
|
|
11409
|
+
readonly CHECKOUT_COMPLETE: "billing.checkout.complete";
|
|
11410
|
+
readonly SUBSCRIPTION_CREATE: "billing.subscription.create";
|
|
11411
|
+
readonly SUBSCRIPTION_CANCEL: "billing.subscription.cancel";
|
|
11412
|
+
readonly SUBSCRIPTION_UPDATE: "billing.subscription.update";
|
|
11413
|
+
readonly PAYMENT_FAILED: "billing.payment.failed";
|
|
11414
|
+
readonly ADMIN_LOGIN: "admin.login";
|
|
11415
|
+
readonly ADMIN_USER_VIEW: "admin.user.view";
|
|
11416
|
+
readonly ADMIN_USER_UPDATE: "admin.user.update";
|
|
11417
|
+
readonly ADMIN_CONFIG_CHANGE: "admin.config.change";
|
|
11418
|
+
readonly RATE_LIMIT_EXCEEDED: "security.rate_limit.exceeded";
|
|
11419
|
+
readonly INVALID_INPUT: "security.input.invalid";
|
|
11420
|
+
readonly UNAUTHORIZED_ACCESS: "security.access.unauthorized";
|
|
11421
|
+
readonly OWNERSHIP_VIOLATION: "security.ownership.violation";
|
|
11422
|
+
readonly WEBHOOK_SIGNATURE_INVALID: "security.webhook.signature_invalid";
|
|
11423
|
+
readonly DATA_EXPORT: "data.export";
|
|
11424
|
+
readonly DATA_DELETE: "data.delete";
|
|
11425
|
+
readonly DATA_UPDATE: "data.update";
|
|
11426
|
+
};
|
|
11427
|
+
type StandardAuditActionType = (typeof StandardAuditActions)[keyof typeof StandardAuditActions];
|
|
10199
11428
|
/**
|
|
10200
|
-
*
|
|
10201
|
-
*
|
|
11429
|
+
* Extract client IP from request headers.
|
|
11430
|
+
* Checks common proxy headers in order of reliability.
|
|
10202
11431
|
*/
|
|
10203
|
-
declare function
|
|
10204
|
-
/** Check if a string contains protocol-prefixed URLs or bare domains */
|
|
10205
|
-
declare function containsUrls(str: string): boolean;
|
|
10206
|
-
/** Check if a string contains HTML tags */
|
|
10207
|
-
declare function containsHtml(str: string): boolean;
|
|
10208
|
-
/** Strip all HTML tags from a string */
|
|
10209
|
-
declare function stripHtml(str: string): string;
|
|
11432
|
+
declare function extractAuditIp(request?: AuditRequest): string | undefined;
|
|
10210
11433
|
/**
|
|
10211
|
-
*
|
|
10212
|
-
* Converts https://evil.com → hxxps://evil[.]com
|
|
11434
|
+
* Extract user agent from request.
|
|
10213
11435
|
*/
|
|
10214
|
-
declare function
|
|
11436
|
+
declare function extractAuditUserAgent(request?: AuditRequest): string | undefined;
|
|
10215
11437
|
/**
|
|
10216
|
-
*
|
|
10217
|
-
* Escapes HTML entities AND defangs any URLs that slipped through validation.
|
|
11438
|
+
* Extract or generate request ID.
|
|
10218
11439
|
*/
|
|
10219
|
-
declare function
|
|
10220
|
-
|
|
11440
|
+
declare function extractAuditRequestId(request?: AuditRequest): string;
|
|
10221
11441
|
/**
|
|
10222
|
-
*
|
|
10223
|
-
*
|
|
10224
|
-
* Framework-agnostic error codes, error class, response types,
|
|
10225
|
-
* and database error mapping for consistent API behavior across apps.
|
|
11442
|
+
* Create an AuditActor from a session object.
|
|
11443
|
+
* Works with Auth.js/NextAuth session shape.
|
|
10226
11444
|
*/
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
readonly CONFLICT: "CONFLICT";
|
|
10234
|
-
readonly RATE_LIMIT_EXCEEDED: "RATE_LIMIT_EXCEEDED";
|
|
10235
|
-
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
10236
|
-
readonly DATABASE_ERROR: "DATABASE_ERROR";
|
|
10237
|
-
readonly EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR";
|
|
10238
|
-
readonly CONFIGURATION_ERROR: "CONFIGURATION_ERROR";
|
|
10239
|
-
};
|
|
10240
|
-
type ApiErrorCodeType = (typeof ApiErrorCode)[keyof typeof ApiErrorCode];
|
|
10241
|
-
/** Custom API Error class with status code and error code */
|
|
10242
|
-
declare class ApiError extends Error {
|
|
10243
|
-
readonly statusCode: number;
|
|
10244
|
-
readonly code: ApiErrorCodeType;
|
|
10245
|
-
readonly details?: unknown;
|
|
10246
|
-
constructor(statusCode: number, message: string, code?: ApiErrorCodeType, details?: unknown);
|
|
10247
|
-
}
|
|
10248
|
-
/** Type guard for ApiError */
|
|
10249
|
-
declare function isApiError(error: unknown): error is ApiError;
|
|
10250
|
-
/** Pre-built error factories */
|
|
10251
|
-
declare const CommonApiErrors: {
|
|
10252
|
-
unauthorized: (msg?: string) => ApiError;
|
|
10253
|
-
forbidden: (msg?: string) => ApiError;
|
|
10254
|
-
notFound: (resource?: string) => ApiError;
|
|
10255
|
-
conflict: (msg?: string) => ApiError;
|
|
10256
|
-
rateLimitExceeded: (msg?: string) => ApiError;
|
|
10257
|
-
validationError: (details?: unknown) => ApiError;
|
|
10258
|
-
internalError: (msg?: string) => ApiError;
|
|
10259
|
-
};
|
|
10260
|
-
/** PostgreSQL error code → HTTP status mapping */
|
|
10261
|
-
declare const PG_ERROR_MAP: Record<string, {
|
|
10262
|
-
status: number;
|
|
10263
|
-
code: ApiErrorCodeType;
|
|
10264
|
-
message: string;
|
|
10265
|
-
}>;
|
|
11445
|
+
declare function createAuditActor(session: {
|
|
11446
|
+
user?: {
|
|
11447
|
+
id?: string;
|
|
11448
|
+
email?: string | null;
|
|
11449
|
+
};
|
|
11450
|
+
} | null | undefined): OpsAuditActor;
|
|
10266
11451
|
/**
|
|
10267
|
-
*
|
|
10268
|
-
*
|
|
11452
|
+
* Create an audit logger instance.
|
|
11453
|
+
*
|
|
11454
|
+
* @param options - Persistence callback and optional logger
|
|
11455
|
+
* @returns Audit logger with log() and createTimedAudit() methods
|
|
10269
11456
|
*/
|
|
10270
|
-
declare function
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
};
|
|
10277
|
-
};
|
|
10278
|
-
/** Standard success response shape */
|
|
10279
|
-
interface ApiSuccessResponse<T = unknown> {
|
|
10280
|
-
success: true;
|
|
10281
|
-
data: T;
|
|
10282
|
-
message?: string;
|
|
10283
|
-
timestamp?: string;
|
|
10284
|
-
}
|
|
10285
|
-
/** Standard paginated response shape */
|
|
10286
|
-
interface ApiPaginatedResponse<T = unknown> extends ApiSuccessResponse<T[]> {
|
|
10287
|
-
pagination: {
|
|
10288
|
-
page: number;
|
|
10289
|
-
limit: number;
|
|
10290
|
-
total: number;
|
|
10291
|
-
totalPages: number;
|
|
10292
|
-
hasMore: boolean;
|
|
11457
|
+
declare function createAuditLogger(options?: OpsAuditLoggerOptions): {
|
|
11458
|
+
log: (event: OpsAuditEvent, request?: AuditRequest) => Promise<OpsAuditRecord>;
|
|
11459
|
+
createTimedAudit: (event: Omit<OpsAuditEvent, "outcome">, request?: AuditRequest) => {
|
|
11460
|
+
success: (metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
|
|
11461
|
+
failure: (reason: string, metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
|
|
11462
|
+
blocked: (reason: string, metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
|
|
10293
11463
|
};
|
|
10294
|
-
}
|
|
10295
|
-
/** Build a pagination metadata object */
|
|
10296
|
-
declare function buildPagination(page: number, limit: number, total: number): {
|
|
10297
|
-
page: number;
|
|
10298
|
-
limit: number;
|
|
10299
|
-
total: number;
|
|
10300
|
-
totalPages: number;
|
|
10301
|
-
hasMore: boolean;
|
|
10302
11464
|
};
|
|
10303
11465
|
|
|
10304
11466
|
/**
|
|
@@ -10838,6 +12000,33 @@ declare class MemoryScheduler implements IScheduler {
|
|
|
10838
12000
|
private completeExecution;
|
|
10839
12001
|
}
|
|
10840
12002
|
|
|
12003
|
+
/**
|
|
12004
|
+
* MemoryCrypto - In-memory ICrypto adapter for testing
|
|
12005
|
+
* Uses Node.js built-in crypto module with keys stored in memory.
|
|
12006
|
+
*/
|
|
12007
|
+
|
|
12008
|
+
declare class MemoryCrypto implements ICrypto {
|
|
12009
|
+
private keys;
|
|
12010
|
+
private activeKeyId;
|
|
12011
|
+
private hmacKey;
|
|
12012
|
+
constructor(options?: {
|
|
12013
|
+
masterKey?: string;
|
|
12014
|
+
hmacKey?: string;
|
|
12015
|
+
});
|
|
12016
|
+
encrypt(plaintext: string, options?: EncryptOptions): Promise<EncryptedField>;
|
|
12017
|
+
decrypt(field: EncryptedField, options?: EncryptOptions): Promise<string>;
|
|
12018
|
+
encryptDeterministic(plaintext: string, options?: EncryptOptions): Promise<DeterministicEncryptedField>;
|
|
12019
|
+
computeHash(plaintext: string): Promise<string>;
|
|
12020
|
+
encryptBatch(fields: Record<string, string>, options?: EncryptOptions): Promise<Record<string, EncryptedField>>;
|
|
12021
|
+
decryptBatch(fields: Record<string, EncryptedField>, options?: EncryptOptions): Promise<Record<string, string>>;
|
|
12022
|
+
rotateKey(): Promise<KeyRotationResult>;
|
|
12023
|
+
reEncrypt(field: EncryptedField, options?: EncryptOptions): Promise<EncryptedField>;
|
|
12024
|
+
listKeys(): Promise<CryptoKeyMetadata[]>;
|
|
12025
|
+
getActiveKeyId(): Promise<string>;
|
|
12026
|
+
healthCheck(): Promise<boolean>;
|
|
12027
|
+
private generateKeyId;
|
|
12028
|
+
}
|
|
12029
|
+
|
|
10841
12030
|
/**
|
|
10842
12031
|
* Supabase Database Adapter
|
|
10843
12032
|
* Production implementation using Supabase as the database provider
|
|
@@ -12795,6 +13984,50 @@ declare class WeaviateRAG implements IRAG {
|
|
|
12795
13984
|
*/
|
|
12796
13985
|
declare function createWeaviateRAG(config: WeaviateRAGConfig): WeaviateRAG;
|
|
12797
13986
|
|
|
13987
|
+
/**
|
|
13988
|
+
* NodeCrypto - Production ICrypto adapter using Node.js built-in crypto
|
|
13989
|
+
*
|
|
13990
|
+
* Architecture:
|
|
13991
|
+
* - Master key (from env/ISecrets) → HKDF → per-deployment DEKs
|
|
13992
|
+
* - AES-256-GCM with 96-bit random IVs for encryption
|
|
13993
|
+
* - HMAC-SHA256 for deterministic/searchable encryption
|
|
13994
|
+
* - Envelope encryption: master key wraps DEKs
|
|
13995
|
+
* - Key rotation: new DEK generated, old marked decrypt-only
|
|
13996
|
+
*
|
|
13997
|
+
* Zero external dependencies — only uses node:crypto.
|
|
13998
|
+
*/
|
|
13999
|
+
|
|
14000
|
+
interface NodeCryptoConfig {
|
|
14001
|
+
/** Master key as hex string (64 hex chars = 32 bytes). Required. */
|
|
14002
|
+
masterKey: string;
|
|
14003
|
+
/** HMAC key as hex string for deterministic hashing. If not provided, derived from master key. */
|
|
14004
|
+
hmacKey?: string;
|
|
14005
|
+
}
|
|
14006
|
+
declare class NodeCrypto implements ICrypto {
|
|
14007
|
+
private masterKey;
|
|
14008
|
+
private hmacKey;
|
|
14009
|
+
private keys;
|
|
14010
|
+
private activeKeyId;
|
|
14011
|
+
private keyCounter;
|
|
14012
|
+
constructor(config: NodeCryptoConfig);
|
|
14013
|
+
encrypt(plaintext: string, options?: EncryptOptions): Promise<EncryptedField>;
|
|
14014
|
+
decrypt(field: EncryptedField, options?: EncryptOptions): Promise<string>;
|
|
14015
|
+
encryptDeterministic(plaintext: string, options?: EncryptOptions): Promise<DeterministicEncryptedField>;
|
|
14016
|
+
computeHash(plaintext: string): Promise<string>;
|
|
14017
|
+
encryptBatch(fields: Record<string, string>, options?: EncryptOptions): Promise<Record<string, EncryptedField>>;
|
|
14018
|
+
decryptBatch(fields: Record<string, EncryptedField>, options?: EncryptOptions): Promise<Record<string, string>>;
|
|
14019
|
+
rotateKey(): Promise<KeyRotationResult>;
|
|
14020
|
+
reEncrypt(field: EncryptedField, options?: EncryptOptions): Promise<EncryptedField>;
|
|
14021
|
+
listKeys(): Promise<CryptoKeyMetadata[]>;
|
|
14022
|
+
getActiveKeyId(): Promise<string>;
|
|
14023
|
+
healthCheck(): Promise<boolean>;
|
|
14024
|
+
/**
|
|
14025
|
+
* Derive a Data Encryption Key from the master key using HKDF.
|
|
14026
|
+
*/
|
|
14027
|
+
private deriveDEK;
|
|
14028
|
+
private generateKeyId;
|
|
14029
|
+
}
|
|
14030
|
+
|
|
12798
14031
|
/**
|
|
12799
14032
|
* Generic OIDC Enterprise SSO Adapter
|
|
12800
14033
|
*
|
|
@@ -13086,4 +14319,224 @@ declare class PostgresTenant implements ITenant {
|
|
|
13086
14319
|
private mapRowToInvitation;
|
|
13087
14320
|
}
|
|
13088
14321
|
|
|
13089
|
-
export { AIChatRequest, AIChatResponse, AICompletionRequest, AICompletionResponse, AIConfig, AIEmbeddingRequest, AIEmbeddingResponse, AIModelConfig, AIModelType, AIProvider, AIStreamCallback, AIStreamChunk, type AIUsageConfig, type AccountCapabilities, type AccountLink, type AccountType, type Address, type AlertType, AnthropicAdapter, type AnthropicAdapterConfig, type ApiAuthentication, type ApiChangelog, type ApiDocumentation, type ApiEndpoint, ApiError, ApiErrorCode, type ApiErrorCodeType, type ApiExample, type ApiKey, type ApiKeyStatus, type ApiKeyType, type ApiKeyValidationResult, type ApiPaginatedResponse, type ApiParameter, type ApiResponse, type ApiSchema, type ApiSchemaProperty, type ApiSuccessResponse, type ApiUsageStats, type ApiUsageTimeSeries, AssembledContext, type AuditActor, type AuditCategory, type AuditEvent, AuditEvents, type AuditEvidence, type AuditLogConfig, type AuditOutcome, type AuditQuery, type AuditQueryResult, type AuditRetentionPolicy, type AuditStats, type AuditTarget, type AuthConfig, type AuthError, type AuthErrorCode, AuthErrorMessages, type AuthEventType, type AuthResult, type AuthSession, type AuthStateChangeCallback, type AuthStorage, type AuthUser, type Balance, type BalanceAmount, type BankAccountDetails, type BatchNotificationOptions, type BillingConfig, type BillingDetails, type BillingPeriod, type Breadcrumb, type Budget, type BudgetStatus, BulkIngestionResult, Bulkhead, type BulkheadOptions, BulkheadRegistry, BulkheadRejectedError, type BulkheadStats, type BullMQConfig, BullMQQueue, type BusinessProfile, type CancelationReason, type CaptureOptions, type CapturePaymentIntentOptions, type CardBrand, type CardDetails, type ChainExecutionResult, CircuitBreaker, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitOpenError, type CircuitState, type CommandStatus, CommonApiErrors, type ComplianceConfig, type ComplianceReport, type ConfirmPaymentIntentOptions, type ConnectedAccount, type ConnectedAccountStatus, type ConsentPreferences, type ConsentPurpose, type ConsentRecord, type ConsentStatus, ContextAssemblyConfig, type ControlFramework, type ControlStatus, type CorrelationData, type CostBreakdown, type Coupon, type CreateAccountLinkOptions, type CreateApiKeyOptions, CreateCollectionOptions, type CreateConnectedAccountOptions, type CreateCustomerOptions, type CreateDsarOptions, type CreatePaymentIntentOptions, type CreatePayoutOptions, type CreateRefundOptions, type CreateSandboxOptions, type CreateScheduleOptions, type CreateTenantOptions, type CreateTransferOptions, type CreateWebhookOptions, type CreditBalance, type CreditTransaction, type CreditType, type CronExpression, CronPresets, type Currency, type Customer, DEFAULT_BULKHEAD_OPTIONS, DEFAULT_CIRCUIT_BREAKER_OPTIONS, DEFAULT_RETRY_OPTIONS, type DataBreachRecord, type DataCategory, type DataInventoryItem, type DataMap, type DataSensitivity, type DataSubjectRequest, type DataType, DatabaseAIUsage, type DatabaseAIUsageConfig, DatabaseAuditLog, type DatabaseAuditLogConfig, DatabaseBilling, type DatabaseBillingConfig, DatabaseCompliance, DatabaseErrorReporter, type DatabaseErrorReporterConfig, DatabaseNotification, type DatabaseNotificationConfig, DatabasePromptStore, type DatabasePromptStoreConfig, DefaultTimeouts, type DeleteAccountOptions, type DeleteHookContext, type DeliveryAttempt, type DeliveryQuery, type DeliveryStatus, type DetailedHealthResponse, type DevPortalConfig, type DeveloperMetrics, type Device, type DeviceAuthMethod, type DeviceCommand, type DeviceConfig, type DeviceConnectionState, type DeviceCredentials, type DeviceGroup, type DeviceGroupQuery, type DeviceLocation, type DeviceQuery, type DeviceQueryResult, type DeviceShadow, type DeviceStatus, type DirectoryAttributeMapping, type DirectoryConfig, DocumentStatus, type DsarAttachment, type DsarNote, type DsarStatus, type DsarType, type DunningActionType, type DunningAttempt, type DunningConfig, type EmailHookContext, EmailMessage, EmailResult, type EnrollMfaOptions, type EnrollMfaResult, type ErrorContext, type ErrorHookContext, type ErrorLevel, type ErrorReport, type ErrorReporterConfig, type EvidenceType, type ExperimentMetrics, type FallbackOptions, type FallbackResult, FallbackStrategies, type FirmwareStatus, type FirmwareUpdate, type FirmwareVersion, type GeneratedSdk, GenericOIDCAuthSSO, type GenericOIDCConfig, GoogleAIAdapter, type GoogleAIAdapterConfig, HTML_TAG_PATTERN, type HealthCheckResult, type HealthEndpoints, type HealthEndpointsOptions, type HealthStatus, type HookRegistry, type HttpMethod, HttpWebhook, type HttpWebhookConfig, IAI, type IAIUsage, type IAuditLog, type IAuth, type IAuthSSO, type IBilling, ICache, type ICompliance, IDatabase, type IDevPortal, type IDevice, IEmail, type IErrorReporter, type IHealth, type IHealthCheckable, ILogger, IMetrics, type INotification, type IPayment, IPlatform, type IPromptStore, IQueryBuilder, IQueue, IRAG, type IScheduler, IStorage, type ITenant, type IWebhook, type InboundWebhookConfig, type InboundWebhookContext, IngestionOptions, IngestionResult, type InsertHookContext, type InviteMemberOptions, type Invoice, type InvoiceLineItem, type InvoiceQuery, type InvoiceStatus, Job, JobEventHandler, JobEventType, type JobHookContext, JobOptions, JobState, type ListTenantsOptions, type LivenessResponse, MemoryAIUsage, MemoryAuditLog, type MemoryAuditLogConfig, MemoryAuth, MemoryAuthSSO, MemoryBilling, MemoryCompliance, MemoryDevPortal, MemoryDevice, MemoryErrorReporter, type MemoryErrorReporterConfig, MemoryNotification, type MemoryNotificationConfig, MemoryPayment, MemoryPromptStore, MemoryRateLimiterStorage, MemoryScheduler, type MemorySchedulerConfig, MemoryTenant, MemoryWebhook, type MemoryWebhookConfig, type Meter, type MetricsEndpoint, type MetricsEndpointOptions, MetricsSummary, type MfaChallenge, type MfaFactor, type MfaFactorType, type Middleware, type MiddlewareChain, type MiddlewareChainOptions, type MiddlewareContext, type NotificationAction, type NotificationCategory, type NotificationChannel, type NotificationConfig, type NotificationData, type NotificationPreferences, type NotificationPriority, type NotificationQuery, type NotificationResult, type NotificationStats, type NotificationStatus, type NotificationTarget, NotificationTemplates, type OAuthOptions, type OAuthProvider, type OAuthResult, type OidcAuthRequest, type OidcAuthResponse, type OidcClaimMapping, type OidcIdpConfig, OpenAIAdapter, type OpenAIAdapterConfig, PG_ERROR_MAP, type ParameterLocation, type PaymentConfig, type PaymentError, type PaymentErrorCode, PaymentErrorMessages, type PaymentEventType, type PaymentIntent, type PaymentMethod, type PaymentMethodType, type PaymentStatus, type PaymentWebhookEvent, type Payout, type PayoutStatus, type PiaMitigation, type PiaRisk, type PiaStatus, PineconeRAG, type PineconeRAGConfig, type PlatformHealthResult, PlatformHealthStatus, type PlatformHooks, type PostgresConfig, PostgresDatabase, PostgresTenant, type PostgresTenantConfig, type Price, type PricingModel, type PricingTier, type PrivacyImpactAssessment, type Product, type Prompt, type PromptChain, type PromptChainStep, type PromptExperiment, type PromptQuery, type PromptQueryResult, type PromptStatus, type PromptStoreConfig, type PromptType, type PromptUsageRecord, type PromptUsageStats, type PromptVariable, type PromptVariant, type PromptVersion, type ProvisioningConfig, type ProvisioningRequest, type ProvisioningResult, type ProvisioningStatus, type PushSubscription, type QueryHookContext, QueryResult, QueueScheduler, type QueueSchedulerConfig, type Quota, type QuotaStatus, type QuotaType, RAGChunk, RAGCollection, RAGConfig, RAGDocument, RAGPipeline, RAGSearchQuery, RAGSearchResponse, RAGSearchResult, type RateLimitAlgorithm, RateLimitError, type RateLimitInfo, type RateLimitOptions, RateLimitPresets, type RateLimiterStorage, type ReadinessResponse, type RecordConsentOptions, RedisCache, type RedisConfig, type Refund, type RefundReason, type RefundStatus, type RenderOptions, type RenderedPrompt, RepeatOptions, ResendEmail, type ResetPasswordOptions, type RetentionAction, type RetentionExecution, type RetentionPolicy, RetryConfigs, type RetryOptions, RetryPredicates, type RetryResult, type RevenueMetrics, type RiskLevel, S3Storage, type SamlAssertion, type SamlAttributeMapping, type SamlAuthRequest, type SamlAuthResponse, type SamlIdpConfig, type SamlNameIdFormat, type SamlSpConfig, type Sandbox, type SandboxConfig, type SandboxLimits, type SandboxStatus, type SandboxUsage, type ScheduleContext, type ScheduleExecution, type ScheduleHandler, type ScheduleQuery, type ScheduleState, type ScheduleUpdateOptions, type ScheduledJob, type SchedulerConfig, type SchedulerStats, type ScimConfig, type ScimUser, type SdkConfig, type SdkFile, type SdkLanguage, type SendCommandOptions, type SendNotificationOptions, type ServiceHealth, type ShadowDelta, type ShadowMetadata, type ShadowUpdate, type SignInWithEmailOptions, type SignInWithMagicLinkOptions, type SignInWithPhoneOptions, type SignUpWithEmailOptions, type SignatureAlgorithm, type SlidingWindowRateLimitOptions, type SmtpConfig, SmtpEmail, type SsoSession, type StartupResponse, StorageFile, type StoredAuditEvent, type StoredNotification, StripePayment, type StripePaymentConfig, type Subscription, type SubscriptionDiscount, type SubscriptionItem, type SubscriptionMetrics, type SubscriptionQuery, type SubscriptionStatus, SupabaseAuth, type SupabaseAuthConfig, SupabaseDatabase, SupabaseStorage, type SupabaseStorageConfig, type TaxBreakdown, type TelemetryMessage, type TelemetryQuery, type TelemetryResult, type Tenant, type TenantBranding, type TenantContext, type TenantDatabaseConfig, type TenantInvitation, type TenantIsolationModel, type TenantMember, type TenantMemberStatus, type TenantQuotas, type TenantResolutionOptions, type TenantResolutionStrategy, type TenantRole, type TenantSecuritySettings, type TenantSettings, type TenantStatus, type TenantUsage, TimeoutError, type TimeoutOptions, type TokenBucketOptions, type TosAcceptance, type Transfer, type TransferStatus, URL_DOMAIN_PATTERN, URL_PROTOCOL_PATTERN, type Unsubscribe, type UpdateCustomerOptions, type UpdateHookContext, type UpdatePasswordOptions, type UpdatePaymentIntentOptions, type UpdateScheduleOptions, type UpdateStatus, type UpdateTenantOptions, type UpdateUserOptions, type UpdateWebhookOptions, type UploadHookContext, UploadOptions, UpstashCache, type UsageAlert, type UsageCategory, type UsageEvent, type UsageInterval, type UsageInvoice, type UsageInvoiceItem, type UsageQuery, type UsageQueryResult, type UsageRecord, type UsageSummary, type UsageSummaryRecord, type UsageTrend, type VerificationResult, type VerifyMfaOptions, type VerifyPhoneOtpOptions, type VerifyWebhookOptions, WeaviateRAG, type WeaviateRAGConfig, type WebhookConfig, type WebhookDelivery, type WebhookEndpoint, type WebhookEvent, WebhookEventTypes, type WebhookQuery, type WebhookState, type WebhookStats, type WebhookTestEndpoint, type WebhookTestEvent, buildPagination, calculateRetryDelay, classifyError, composeHookRegistries, containsHtml, containsUrls, correlationContext, createAnthropicAdapter, createAuthError, createBulkhead, createCacheMiddleware, createCachedFallback, createCircuitBreaker, createDefaultPreferences, createErrorReport, createExpressHealthHandlers, createExpressMetricsHandler, createGoogleAIAdapter, createHealthEndpoints, createHealthServer, createHookRegistry, createIpKeyGenerator, createJobContext, createLoggingMiddleware, createMetricsEndpoint, createMetricsMiddleware, createMetricsServer, createMiddlewareChain, createMiddlewareContext, createObservabilityServer, createOpenAIAdapter, createPaymentError, createPineconeRAG, createRateLimitMiddleware, createRequestContext, createRequestIdMiddleware, createSlowQueryMiddleware, createTenantMiddleware, createTimeoutMiddleware, createUserKeyGenerator, createWeaviateRAG, defangUrl, describeCron, escapeHtml, filterChannelsByPreferences, formatAmount, generateAuditId, generateChecksum, generateDeliveryId, generateErrorId, generateEventId, generateFingerprint, generateNotificationId, generatePaymentId, generateScheduleId, generateSecureToken, generateWebhookId, generateWebhookSecret, getContext, getCorrelationId, getLogMeta, getNextCronRun, getRequestId, getTenantId, getTraceId, getUserId, isApiError, isAuthError, isInContext, isInQuietHours, isPaymentError, isValidCron, matchAction, matchEventType, raceTimeout, retryable, runWithContext, runWithContextAsync, sanitizeForEmail, stripHtml, timedHealthCheck, toHealthCheckResult, withCorrelation, withCorrelationAsync, withFallback, withFallbackChain, withFallbackResult, withRetry, withRetryResult, withTimeout, withTimeoutWrapper };
|
|
14322
|
+
/**
|
|
14323
|
+
* Environment Variable Helpers
|
|
14324
|
+
*
|
|
14325
|
+
* Type-safe, fail-fast utilities for reading environment variables.
|
|
14326
|
+
* Every app needs these — extracted from DLL, WIAN, and OSS patterns.
|
|
14327
|
+
*
|
|
14328
|
+
* @example
|
|
14329
|
+
* ```typescript
|
|
14330
|
+
* import { getRequiredEnv, getOptionalEnv, getBoolEnv, validateEnvVars } from '@digilogiclabs/platform-core'
|
|
14331
|
+
*
|
|
14332
|
+
* const config = {
|
|
14333
|
+
* stripe: { secretKey: getRequiredEnv('STRIPE_SECRET_KEY') },
|
|
14334
|
+
* redis: { url: getOptionalEnv('REDIS_URL', '') },
|
|
14335
|
+
* features: { debug: getBoolEnv('DEBUG', false) },
|
|
14336
|
+
* }
|
|
14337
|
+
*
|
|
14338
|
+
* // Validate at startup
|
|
14339
|
+
* validateEnvVars({
|
|
14340
|
+
* required: ['STRIPE_SECRET_KEY', 'DATABASE_URL'],
|
|
14341
|
+
* requireOneOf: [['DATABASE_URL', 'SUPABASE_URL']], // at least one
|
|
14342
|
+
* validators: {
|
|
14343
|
+
* DATABASE_URL: (v) => v.startsWith('postgres') || 'must start with postgres://',
|
|
14344
|
+
* ADMIN_SECRET: (v) => v.length >= 32 || 'must be at least 32 characters',
|
|
14345
|
+
* },
|
|
14346
|
+
* })
|
|
14347
|
+
* ```
|
|
14348
|
+
*/
|
|
14349
|
+
/**
|
|
14350
|
+
* Get a required environment variable.
|
|
14351
|
+
* Throws immediately if not set — fail-fast at startup.
|
|
14352
|
+
*/
|
|
14353
|
+
declare function getRequiredEnv(key: string): string;
|
|
14354
|
+
/**
|
|
14355
|
+
* Get an optional environment variable with a default value.
|
|
14356
|
+
*/
|
|
14357
|
+
declare function getOptionalEnv(key: string, defaultValue: string): string;
|
|
14358
|
+
/**
|
|
14359
|
+
* Get a boolean environment variable.
|
|
14360
|
+
* Treats "true" and "1" as true, everything else as false.
|
|
14361
|
+
*/
|
|
14362
|
+
declare function getBoolEnv(key: string, defaultValue?: boolean): boolean;
|
|
14363
|
+
/**
|
|
14364
|
+
* Get a numeric environment variable with a default.
|
|
14365
|
+
*/
|
|
14366
|
+
declare function getIntEnv(key: string, defaultValue: number): number;
|
|
14367
|
+
/**
|
|
14368
|
+
* Configuration for environment validation.
|
|
14369
|
+
*/
|
|
14370
|
+
interface EnvValidationConfig {
|
|
14371
|
+
/** Variables that must be set (non-empty) */
|
|
14372
|
+
required?: string[];
|
|
14373
|
+
/** Groups where at least one must be set (e.g., DATABASE_URL or SUPABASE_URL) */
|
|
14374
|
+
requireOneOf?: string[][];
|
|
14375
|
+
/** Custom validators — return true or an error message */
|
|
14376
|
+
validators?: Record<string, (value: string) => true | string>;
|
|
14377
|
+
}
|
|
14378
|
+
/**
|
|
14379
|
+
* Validation result with categorized errors.
|
|
14380
|
+
*/
|
|
14381
|
+
interface EnvValidationResult {
|
|
14382
|
+
valid: boolean;
|
|
14383
|
+
missing: string[];
|
|
14384
|
+
invalid: {
|
|
14385
|
+
key: string;
|
|
14386
|
+
reason: string;
|
|
14387
|
+
}[];
|
|
14388
|
+
missingOneOf: string[][];
|
|
14389
|
+
}
|
|
14390
|
+
/**
|
|
14391
|
+
* Validate environment variables against a configuration.
|
|
14392
|
+
*
|
|
14393
|
+
* @throws Error with details about all missing/invalid variables
|
|
14394
|
+
*/
|
|
14395
|
+
declare function validateEnvVars(config: EnvValidationConfig): void;
|
|
14396
|
+
/**
|
|
14397
|
+
* Check environment variables without throwing.
|
|
14398
|
+
* Returns a result object for custom error handling.
|
|
14399
|
+
*/
|
|
14400
|
+
declare function checkEnvVars(config: EnvValidationConfig): EnvValidationResult;
|
|
14401
|
+
/**
|
|
14402
|
+
* Get a redacted config summary for debugging.
|
|
14403
|
+
* Shows which variables are configured without exposing values.
|
|
14404
|
+
*/
|
|
14405
|
+
declare function getEnvSummary(keys: string[]): Record<string, boolean>;
|
|
14406
|
+
|
|
14407
|
+
/**
|
|
14408
|
+
* Application Logger
|
|
14409
|
+
*
|
|
14410
|
+
* Structured logger with child loggers, request correlation,
|
|
14411
|
+
* and operation timing. Builds on ConsoleLogger but adds the
|
|
14412
|
+
* patterns every app needs: component loggers, request loggers,
|
|
14413
|
+
* job loggers, and timing wrappers.
|
|
14414
|
+
*
|
|
14415
|
+
* @example
|
|
14416
|
+
* ```typescript
|
|
14417
|
+
* import { createAppLogger } from '@digilogiclabs/platform-core'
|
|
14418
|
+
*
|
|
14419
|
+
* const logger = createAppLogger({ service: 'my-app' })
|
|
14420
|
+
*
|
|
14421
|
+
* // Child loggers for components
|
|
14422
|
+
* const authLogger = logger.child({ component: 'auth' })
|
|
14423
|
+
* authLogger.info('User signed in', { userId: '123' })
|
|
14424
|
+
*
|
|
14425
|
+
* // Request-scoped logger with correlation ID
|
|
14426
|
+
* const reqLogger = logger.forRequest(request, 'create-server')
|
|
14427
|
+
* reqLogger.info('Processing request')
|
|
14428
|
+
*
|
|
14429
|
+
* // Timed operations
|
|
14430
|
+
* const result = await logger.timed('fetchArticles', () => fetchArticles(), { count: 10 })
|
|
14431
|
+
* ```
|
|
14432
|
+
*/
|
|
14433
|
+
interface AppLogContext {
|
|
14434
|
+
[key: string]: unknown;
|
|
14435
|
+
}
|
|
14436
|
+
/**
|
|
14437
|
+
* Structured logger interface shared across all apps.
|
|
14438
|
+
*/
|
|
14439
|
+
interface AppLogger {
|
|
14440
|
+
debug(message: string, context?: AppLogContext): void;
|
|
14441
|
+
info(message: string, context?: AppLogContext): void;
|
|
14442
|
+
warn(message: string, context?: AppLogContext): void;
|
|
14443
|
+
error(message: string, context?: AppLogContext): void;
|
|
14444
|
+
/** Create a child logger with additional persistent context */
|
|
14445
|
+
child(context: AppLogContext): AppLogger;
|
|
14446
|
+
/** Create a request-scoped logger with correlation ID */
|
|
14447
|
+
forRequest(request: Request, operation: string): AppLogger;
|
|
14448
|
+
/** Create a job-scoped logger */
|
|
14449
|
+
forJob(jobType: string, jobId: string, context?: AppLogContext): AppLogger;
|
|
14450
|
+
/**
|
|
14451
|
+
* Execute an async operation with automatic timing.
|
|
14452
|
+
* Logs start (debug), success with duration (info), or failure with duration (error).
|
|
14453
|
+
*/
|
|
14454
|
+
timed<T>(operation: string, fn: () => Promise<T>, context?: AppLogContext): Promise<T>;
|
|
14455
|
+
}
|
|
14456
|
+
interface AppLoggerOptions {
|
|
14457
|
+
/** Service/app name for log context */
|
|
14458
|
+
service: string;
|
|
14459
|
+
/** Minimum log level (default: 'debug' in dev, 'info' in production) */
|
|
14460
|
+
minLevel?: "debug" | "info" | "warn" | "error";
|
|
14461
|
+
/** Custom output handler (default: console with JSON in prod, pretty in dev) */
|
|
14462
|
+
output?: (level: string, message: string, context: AppLogContext) => void;
|
|
14463
|
+
/** Error reporter callback — called on error() logs */
|
|
14464
|
+
onError?: (message: string, context: AppLogContext) => void;
|
|
14465
|
+
}
|
|
14466
|
+
/**
|
|
14467
|
+
* Create an application logger.
|
|
14468
|
+
*
|
|
14469
|
+
* @param options - Logger configuration
|
|
14470
|
+
* @returns Structured logger with child, request, job, and timing support
|
|
14471
|
+
*/
|
|
14472
|
+
declare function createAppLogger(options: AppLoggerOptions): AppLogger;
|
|
14473
|
+
|
|
14474
|
+
/**
|
|
14475
|
+
* Redis Client Factory
|
|
14476
|
+
*
|
|
14477
|
+
* Shared ioredis singleton factory with retry strategy and graceful
|
|
14478
|
+
* degradation. All self-hosted apps need a Redis client for rate
|
|
14479
|
+
* limiting, caching, audit logging, webhook deduplication, etc.
|
|
14480
|
+
*
|
|
14481
|
+
* This provides a raw ioredis client — for higher-level cache
|
|
14482
|
+
* operations, use RedisCache from the adapters module.
|
|
14483
|
+
*
|
|
14484
|
+
* @example
|
|
14485
|
+
* ```typescript
|
|
14486
|
+
* import { createRedisClient, getSharedRedis } from '@digilogiclabs/platform-core'
|
|
14487
|
+
*
|
|
14488
|
+
* // Option 1: Shared singleton (recommended for most apps)
|
|
14489
|
+
* const redis = getSharedRedis() // null if REDIS_URL not set
|
|
14490
|
+
*
|
|
14491
|
+
* // Option 2: Custom client with options
|
|
14492
|
+
* const redis = createRedisClient({
|
|
14493
|
+
* url: process.env.REDIS_URL,
|
|
14494
|
+
* keyPrefix: 'myapp:',
|
|
14495
|
+
* maxRetries: 5,
|
|
14496
|
+
* })
|
|
14497
|
+
* ```
|
|
14498
|
+
*/
|
|
14499
|
+
|
|
14500
|
+
interface RedisClientOptions {
|
|
14501
|
+
/** Redis connection URL (redis://...) */
|
|
14502
|
+
url: string;
|
|
14503
|
+
/** Key prefix for namespace isolation (e.g., 'dll:', 'wian:') */
|
|
14504
|
+
keyPrefix?: string;
|
|
14505
|
+
/** Max retries per request (default: 3) */
|
|
14506
|
+
maxRetries?: number;
|
|
14507
|
+
/** Use lazy connect — don't connect until first command (default: true) */
|
|
14508
|
+
lazyConnect?: boolean;
|
|
14509
|
+
/** Logger for connection events (default: console) */
|
|
14510
|
+
logger?: {
|
|
14511
|
+
error: (msg: string, meta?: Record<string, unknown>) => void;
|
|
14512
|
+
info?: (msg: string, meta?: Record<string, unknown>) => void;
|
|
14513
|
+
};
|
|
14514
|
+
/** Suppress connection error logs (useful for tests) */
|
|
14515
|
+
silent?: boolean;
|
|
14516
|
+
}
|
|
14517
|
+
/**
|
|
14518
|
+
* Create a new ioredis client with sensible defaults.
|
|
14519
|
+
*
|
|
14520
|
+
* Features:
|
|
14521
|
+
* - Exponential backoff retry strategy (200ms, 400ms, 600ms)
|
|
14522
|
+
* - Automatic reconnection
|
|
14523
|
+
* - Optional key prefix for multi-app isolation
|
|
14524
|
+
* - Connection error logging (suppressible)
|
|
14525
|
+
*/
|
|
14526
|
+
declare function createRedisClient(options: RedisClientOptions): Redis$2;
|
|
14527
|
+
/**
|
|
14528
|
+
* Get the shared Redis client singleton.
|
|
14529
|
+
*
|
|
14530
|
+
* Returns null if REDIS_URL is not configured — callers should
|
|
14531
|
+
* handle this gracefully (fail-open pattern).
|
|
14532
|
+
*
|
|
14533
|
+
* Reads from `REDIS_URL` and optionally `REDIS_KEY_PREFIX`.
|
|
14534
|
+
*/
|
|
14535
|
+
declare function getSharedRedis(): Redis$2 | null;
|
|
14536
|
+
/**
|
|
14537
|
+
* Close the shared Redis client.
|
|
14538
|
+
* Call during graceful shutdown.
|
|
14539
|
+
*/
|
|
14540
|
+
declare function closeSharedRedis(): Promise<void>;
|
|
14541
|
+
|
|
14542
|
+
export { AIChatRequest, AIChatResponse, AICompletionRequest, AICompletionResponse, AIConfig, AIEmbeddingRequest, AIEmbeddingResponse, AIModelConfig, AIModelType, AIProvider, AIStreamCallback, AIStreamChunk, type AIUsageConfig, type AccountCapabilities, type AccountLink, type AccountType, type Address, type AlertType, type AllowlistConfig, AnthropicAdapter, type AnthropicAdapterConfig, type ApiAuthentication, type ApiChangelog, type ApiDocumentation, type ApiEndpoint, ApiError, ApiErrorCode, type ApiErrorCodeType, type ApiExample, type ApiKey, type ApiKeyStatus, type ApiKeyType, type ApiKeyValidationResult, type ApiPaginatedResponse, type ApiParameter, type ApiResponse, type ApiSchema, type ApiSchemaProperty, type ApiSecurityConfig, type ApiSecurityContext, type ApiSuccessResponse, type ApiUsageStats, type ApiUsageTimeSeries, type AppLogContext, type AppLogger, type AppLoggerOptions, AssembledContext, type AuditActor, type AuditCategory, type AuditEvent, AuditEvents, type AuditEvidence, type AuditLogConfig, type AuditOutcome, type AuditQuery, type AuditQueryResult, type AuditRequest, type AuditRetentionPolicy, type AuditStats, type AuditTarget, type AuthConfig, type AuthCookiesConfig, type AuthError, type AuthErrorCode, AuthErrorMessages, type AuthEventType, type AuthMethod, type AuthResult, type AuthSession, type AuthStateChangeCallback, type AuthStorage, type AuthUser, type Balance, type BalanceAmount, type BankAccountDetails, type BatchNotificationOptions, type BillingConfig, type BillingDetails, type BillingPeriod, type Breadcrumb, type Budget, type BudgetStatus, BulkIngestionResult, Bulkhead, type BulkheadOptions, BulkheadRegistry, BulkheadRejectedError, type BulkheadStats, type BullMQConfig, BullMQQueue, type BusinessProfile, type CancelationReason, type CaptureOptions, type CapturePaymentIntentOptions, type CardBrand, type CardDetails, type ChainExecutionResult, CircuitBreaker, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitOpenError, type CircuitState, type CommandStatus, CommonApiErrors, CommonRateLimits, type ComplianceConfig, type ComplianceReport, type ConfirmPaymentIntentOptions, type ConnectedAccount, type ConnectedAccountStatus, type ConsentPreferences, type ConsentPurpose, type ConsentRecord, type ConsentStatus, ContextAssemblyConfig, type ControlFramework, type ControlStatus, type CorrelationData, type CostBreakdown, type Coupon, type CreateAccountLinkOptions, type CreateApiKeyOptions, CreateCollectionOptions, type CreateConnectedAccountOptions, type CreateCustomerOptions, type CreateDsarOptions, type CreatePaymentIntentOptions, type CreatePayoutOptions, type CreateRefundOptions, type CreateSandboxOptions, type CreateScheduleOptions, type CreateTenantOptions, type CreateTransferOptions, type CreateWebhookOptions, type CreditBalance, type CreditTransaction, type CreditType, type CronExpression, CronPresets, CryptoKeyMetadata, type Currency, type Customer, DEFAULT_BULKHEAD_OPTIONS, DEFAULT_CIRCUIT_BREAKER_OPTIONS, DEFAULT_RETRY_OPTIONS, type DataBreachRecord, type DataCategory, type DataInventoryItem, type DataMap, type DataSensitivity, type DataSubjectRequest, type DataType, DatabaseAIUsage, type DatabaseAIUsageConfig, DatabaseAuditLog, type DatabaseAuditLogConfig, DatabaseBilling, type DatabaseBillingConfig, DatabaseCompliance, DatabaseErrorReporter, type DatabaseErrorReporterConfig, DatabaseNotification, type DatabaseNotificationConfig, DatabasePromptStore, type DatabasePromptStoreConfig, type DateRangeInput, DateRangeSchema, DefaultTimeouts, type DeleteAccountOptions, type DeleteHookContext, type DeliveryAttempt, type DeliveryQuery, type DeliveryStatus, type DeploymentStage, type DetailedHealthResponse, DeterministicEncryptedField, type DevPortalConfig, type DeveloperMetrics, type Device, type DeviceAuthMethod, type DeviceCommand, type DeviceConfig, type DeviceConnectionState, type DeviceCredentials, type DeviceGroup, type DeviceGroupQuery, type DeviceLocation, type DeviceQuery, type DeviceQueryResult, type DeviceShadow, type DeviceStatus, type DirectoryAttributeMapping, type DirectoryConfig, DocumentStatus, type DsarAttachment, type DsarNote, type DsarStatus, type DsarType, type DunningActionType, type DunningAttempt, type DunningConfig, type EmailHookContext, type EmailInput, EmailMessage, EmailResult, EmailSchema, EncryptOptions, EncryptedField, type EnrollMfaOptions, type EnrollMfaResult, type EnvValidationConfig, type EnvValidationResult, type ErrorContext, type ErrorHookContext, type ErrorLevel, type ErrorReport, type ErrorReporterConfig, type EvidenceType, type ExperimentMetrics, type FallbackOptions, type FallbackResult, FallbackStrategies, type FirmwareStatus, type FirmwareUpdate, type FirmwareVersion, type FlagDefinition, type FlagDefinitions, type FlagValue, type GeneratedSdk, GenericOIDCAuthSSO, type GenericOIDCConfig, GoogleAIAdapter, type GoogleAIAdapterConfig, HTML_TAG_PATTERN, type HealthCheckResult, type HealthEndpoints, type HealthEndpointsOptions, type HealthStatus, type HookRegistry, type HttpMethod, HttpWebhook, type HttpWebhookConfig, IAI, type IAIUsage, type IAuditLog, type IAuth, type IAuthSSO, type IBilling, ICache, type ICompliance, ICrypto, IDatabase, type IDevPortal, type IDevice, IEmail, type IErrorReporter, type IHealth, type IHealthCheckable, ILogger, IMetrics, type INotification, type IPayment, IPlatform, type IPromptStore, IQueryBuilder, IQueue, IRAG, type IScheduler, IStorage, type ITenant, type IWebhook, type InboundWebhookConfig, type InboundWebhookContext, IngestionOptions, IngestionResult, type InsertHookContext, type InviteMemberOptions, type Invoice, type InvoiceLineItem, type InvoiceQuery, type InvoiceStatus, Job, JobEventHandler, JobEventType, type JobHookContext, JobOptions, JobState, KEYCLOAK_DEFAULT_ROLES, KeyRotationResult, type KeycloakCallbacksConfig, type KeycloakConfig, type KeycloakJwtFields, type KeycloakTokenSet, type ListTenantsOptions, type LivenessResponse, type LoginInput, LoginSchema, MemoryAIUsage, MemoryAuditLog, type MemoryAuditLogConfig, MemoryAuth, MemoryAuthSSO, MemoryBilling, MemoryCompliance, MemoryCrypto, MemoryDevPortal, MemoryDevice, MemoryErrorReporter, type MemoryErrorReporterConfig, MemoryNotification, type MemoryNotificationConfig, MemoryPayment, MemoryPromptStore, MemoryRateLimiterStorage, MemoryScheduler, type MemorySchedulerConfig, MemoryTenant, MemoryWebhook, type MemoryWebhookConfig, type Meter, type MetricsEndpoint, type MetricsEndpointOptions, MetricsSummary, type MfaChallenge, type MfaFactor, type MfaFactorType, type Middleware, type MiddlewareChain, type MiddlewareChainOptions, type MiddlewareContext, NodeCrypto, type NodeCryptoConfig, type NotificationAction, type NotificationCategory, type NotificationChannel, type NotificationConfig, type NotificationData, type NotificationPreferences, type NotificationPriority, type NotificationQuery, type NotificationResult, type NotificationStats, type NotificationStatus, type NotificationTarget, NotificationTemplates, type OAuthOptions, type OAuthProvider, type OAuthResult, type OidcAuthRequest, type OidcAuthResponse, type OidcClaimMapping, type OidcIdpConfig, OpenAIAdapter, type OpenAIAdapterConfig, type OpsAuditActor, type OpsAuditEvent, type OpsAuditLoggerOptions, type OpsAuditRecord, type OpsAuditResource, PG_ERROR_MAP, type PaginationInput, PaginationSchema, type ParameterLocation, PasswordSchema, type PaymentConfig, type PaymentError, type PaymentErrorCode, PaymentErrorMessages, type PaymentEventType, type PaymentIntent, type PaymentMethod, type PaymentMethodType, type PaymentStatus, type PaymentWebhookEvent, type Payout, type PayoutStatus, PersonNameSchema, PhoneSchema, type PiaMitigation, type PiaRisk, type PiaStatus, PineconeRAG, type PineconeRAGConfig, type PlatformHealthResult, PlatformHealthStatus, type PlatformHooks, type PostgresConfig, PostgresDatabase, PostgresTenant, type PostgresTenantConfig, type Price, type PricingModel, type PricingTier, type PrivacyImpactAssessment, type Product, type Prompt, type PromptChain, type PromptChainStep, type PromptExperiment, type PromptQuery, type PromptQueryResult, type PromptStatus, type PromptStoreConfig, type PromptType, type PromptUsageRecord, type PromptUsageStats, type PromptVariable, type PromptVariant, type PromptVersion, type ProvisioningConfig, type ProvisioningRequest, type ProvisioningResult, type ProvisioningStatus, type PushSubscription, type QueryHookContext, QueryResult, QueueScheduler, type QueueSchedulerConfig, type Quota, type QuotaStatus, type QuotaType, RAGChunk, RAGCollection, RAGConfig, RAGDocument, RAGPipeline, RAGSearchQuery, RAGSearchResponse, RAGSearchResult, type RateLimitAlgorithm, type RateLimitCheckResult, RateLimitError, type RateLimitInfo, type RateLimitOptions, type RateLimitPreset, RateLimitPresets, type RateLimitRule, type RateLimitStore, type RateLimiterStorage, type ReadinessResponse, type RecordConsentOptions, type RedirectCallbackConfig, RedisCache, type RedisClientOptions, type RedisConfig, type Refund, type RefundReason, type RefundStatus, type RenderOptions, type RenderedPrompt, RepeatOptions, ResendEmail, type ResetPasswordOptions, type ResolvedFlags, type RetentionAction, type RetentionExecution, type RetentionPolicy, RetryConfigs, type RetryOptions, RetryPredicates, type RetryResult, type RevenueMetrics, type RiskLevel, type RouteAuditConfig, S3Storage, type SamlAssertion, type SamlAttributeMapping, type SamlAuthRequest, type SamlAuthResponse, type SamlIdpConfig, type SamlNameIdFormat, type SamlSpConfig, type Sandbox, type SandboxConfig, type SandboxLimits, type SandboxStatus, type SandboxUsage, type ScheduleContext, type ScheduleExecution, type ScheduleHandler, type ScheduleQuery, type ScheduleState, type ScheduleUpdateOptions, type ScheduledJob, type SchedulerConfig, type SchedulerStats, type ScimConfig, type ScimUser, type SdkConfig, type SdkFile, type SdkLanguage, type SearchQueryInput, SearchQuerySchema, type SecuritySession, type SendCommandOptions, type SendNotificationOptions, type ServiceHealth, type ShadowDelta, type ShadowMetadata, type ShadowUpdate, type SignInWithEmailOptions, type SignInWithMagicLinkOptions, type SignInWithPhoneOptions, type SignUpWithEmailOptions, type SignatureAlgorithm, type SignupInput, SignupSchema, type SlidingWindowRateLimitOptions, SlugSchema, type SmtpConfig, SmtpEmail, type SsoSession, type StandardAuditActionType, StandardAuditActions, StandardRateLimitPresets, type StartupResponse, StorageFile, type StoredAuditEvent, type StoredNotification, StripePayment, type StripePaymentConfig, type Subscription, type SubscriptionDiscount, type SubscriptionItem, type SubscriptionMetrics, type SubscriptionQuery, type SubscriptionStatus, SupabaseAuth, type SupabaseAuthConfig, SupabaseDatabase, SupabaseStorage, type SupabaseStorageConfig, type TaxBreakdown, type TelemetryMessage, type TelemetryQuery, type TelemetryResult, type Tenant, type TenantBranding, type TenantContext, type TenantDatabaseConfig, type TenantInvitation, type TenantIsolationModel, type TenantMember, type TenantMemberStatus, type TenantQuotas, type TenantResolutionOptions, type TenantResolutionStrategy, type TenantRole, type TenantSecuritySettings, type TenantSettings, type TenantStatus, type TenantUsage, TimeoutError, type TimeoutOptions, type TokenBucketOptions, type TokenRefreshResult, type TosAcceptance, type Transfer, type TransferStatus, URL_DOMAIN_PATTERN, URL_PROTOCOL_PATTERN, type Unsubscribe, type UpdateCustomerOptions, type UpdateHookContext, type UpdatePasswordOptions, type UpdatePaymentIntentOptions, type UpdateScheduleOptions, type UpdateStatus, type UpdateTenantOptions, type UpdateUserOptions, type UpdateWebhookOptions, type UploadHookContext, UploadOptions, UpstashCache, type UsageAlert, type UsageCategory, type UsageEvent, type UsageInterval, type UsageInvoice, type UsageInvoiceItem, type UsageQuery, type UsageQueryResult, type UsageRecord, type UsageSummary, type UsageSummaryRecord, type UsageTrend, type VerificationResult, type VerifyMfaOptions, type VerifyPhoneOtpOptions, type VerifyWebhookOptions, WeaviateRAG, type WeaviateRAGConfig, type WebhookConfig, type WebhookDelivery, type WebhookEndpoint, type WebhookEvent, WebhookEventTypes, type WebhookQuery, type WebhookState, type WebhookStats, type WebhookTestEndpoint, type WebhookTestEvent, WrapperPresets, buildAllowlist, buildAuthCookies, buildErrorBody, buildKeycloakCallbacks, buildPagination, buildRateLimitHeaders, buildRateLimitResponseHeaders, buildRedirectCallback, buildTokenRefreshParams, calculateRetryDelay, checkEnvVars, checkRateLimit, classifyError, closeSharedRedis, composeHookRegistries, constantTimeEqual, containsHtml, containsUrls, correlationContext, createAnthropicAdapter, createAppLogger, createAuditActor, createAuditLogger, createAuthError, createBulkhead, createCacheMiddleware, createCachedFallback, createCircuitBreaker, createDefaultPreferences, createErrorReport, createExpressHealthHandlers, createExpressMetricsHandler, createFeatureFlags, createGoogleAIAdapter, createHealthEndpoints, createHealthServer, createHookRegistry, createIpKeyGenerator, createJobContext, createLoggingMiddleware, createMemoryRateLimitStore, createMetricsEndpoint, createMetricsMiddleware, createMetricsServer, createMiddlewareChain, createMiddlewareContext, createObservabilityServer, createOpenAIAdapter, createPaymentError, createPineconeRAG, createRateLimitMiddleware, createRedisClient, createRequestContext, createRequestIdMiddleware, createSafeTextSchema, createSlowQueryMiddleware, createTenantMiddleware, createTimeoutMiddleware, createUserKeyGenerator, createWeaviateRAG, defangUrl, describeCron, detectStage, escapeHtml, extractAuditIp, extractAuditRequestId, extractAuditUserAgent, extractClientIp, filterChannelsByPreferences, formatAmount, generateAuditId, generateChecksum, generateDeliveryId, generateErrorId, generateEventId, generateFingerprint, generateNotificationId, generatePaymentId, generateScheduleId, generateSecureToken, generateWebhookId, generateWebhookSecret, getBoolEnv, getContext, getCorrelationId, getEndSessionEndpoint, getEnvSummary, getIntEnv, getLogMeta, getNextCronRun, getOptionalEnv, getRateLimitStatus, getRequestId, getRequiredEnv, getSharedRedis, getTenantId, getTokenEndpoint, getTraceId, getUserId, hasAllRoles, hasAnyRole, hasRole, isAllowlisted, isApiError, isAuthError, isInContext, isInQuietHours, isPaymentError, isTokenExpired, isValidCron, matchAction, matchEventType, parseKeycloakRoles, raceTimeout, refreshKeycloakToken, resetRateLimitForKey, resolveIdentifier, resolveRateLimitIdentifier, retryable, runWithContext, runWithContextAsync, sanitizeApiError, sanitizeForEmail, stripHtml, timedHealthCheck, toHealthCheckResult, validateEnvVars, withCorrelation, withCorrelationAsync, withFallback, withFallbackChain, withFallbackResult, withRetry, withRetryResult, withTimeout, withTimeoutWrapper };
|