@venturekit/runtime 0.0.0-dev.20260312012510 → 0.0.0-dev.20260329102450

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +1 -1
  2. package/dist/config/env.d.ts +62 -0
  3. package/dist/config/env.d.ts.map +1 -0
  4. package/dist/config/env.js +98 -0
  5. package/dist/config/env.js.map +1 -0
  6. package/dist/config/secrets.d.ts +67 -0
  7. package/dist/config/secrets.d.ts.map +1 -0
  8. package/dist/config/secrets.js +132 -0
  9. package/dist/config/secrets.js.map +1 -0
  10. package/dist/handler/adapter.d.ts.map +1 -0
  11. package/dist/{adapter.js → handler/adapter.js} +5 -44
  12. package/dist/handler/adapter.js.map +1 -0
  13. package/dist/{context.d.ts → handler/context.d.ts} +44 -3
  14. package/dist/handler/context.d.ts.map +1 -0
  15. package/dist/{context.js → handler/context.js} +9 -9
  16. package/dist/handler/context.js.map +1 -0
  17. package/dist/handler/errors.d.ts.map +1 -0
  18. package/dist/{errors.js → handler/errors.js} +11 -25
  19. package/dist/handler/errors.js.map +1 -0
  20. package/dist/{handler.d.ts → handler/handler.d.ts} +36 -3
  21. package/dist/handler/handler.d.ts.map +1 -0
  22. package/dist/{handler.js → handler/handler.js} +59 -23
  23. package/dist/handler/handler.js.map +1 -0
  24. package/dist/handler/response.d.ts.map +1 -0
  25. package/dist/{response.js → handler/response.js} +9 -17
  26. package/dist/handler/response.js.map +1 -0
  27. package/dist/handler/task-handler.d.ts +192 -0
  28. package/dist/handler/task-handler.d.ts.map +1 -0
  29. package/dist/handler/task-handler.js +262 -0
  30. package/dist/handler/task-handler.js.map +1 -0
  31. package/dist/index.d.ts +33 -14
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +30 -48
  34. package/dist/index.js.map +1 -1
  35. package/dist/{logger.d.ts → logging/logger.d.ts} +1 -1
  36. package/dist/logging/logger.d.ts.map +1 -0
  37. package/dist/{logger.js → logging/logger.js} +8 -16
  38. package/dist/logging/logger.js.map +1 -0
  39. package/dist/logging/tracing.d.ts +51 -0
  40. package/dist/logging/tracing.d.ts.map +1 -0
  41. package/dist/logging/tracing.js +77 -0
  42. package/dist/logging/tracing.js.map +1 -0
  43. package/dist/middleware/middleware.d.ts +120 -0
  44. package/dist/middleware/middleware.d.ts.map +1 -0
  45. package/dist/middleware/middleware.js +270 -0
  46. package/dist/middleware/middleware.js.map +1 -0
  47. package/dist/middleware/rate-limit-store.d.ts +153 -0
  48. package/dist/middleware/rate-limit-store.d.ts.map +1 -0
  49. package/dist/middleware/rate-limit-store.js +182 -0
  50. package/dist/middleware/rate-limit-store.js.map +1 -0
  51. package/dist/openapi/openapi.d.ts +147 -0
  52. package/dist/openapi/openapi.d.ts.map +1 -0
  53. package/dist/openapi/openapi.js +235 -0
  54. package/dist/openapi/openapi.js.map +1 -0
  55. package/dist/openapi.d.ts +10 -0
  56. package/dist/openapi.d.ts.map +1 -0
  57. package/dist/openapi.js +9 -0
  58. package/dist/openapi.js.map +1 -0
  59. package/dist/patterns/circuit-breaker.d.ts +78 -0
  60. package/dist/patterns/circuit-breaker.d.ts.map +1 -0
  61. package/dist/patterns/circuit-breaker.js +113 -0
  62. package/dist/patterns/circuit-breaker.js.map +1 -0
  63. package/dist/patterns/idempotency.d.ts +175 -0
  64. package/dist/patterns/idempotency.d.ts.map +1 -0
  65. package/dist/patterns/idempotency.js +305 -0
  66. package/dist/patterns/idempotency.js.map +1 -0
  67. package/dist/patterns/invoke.d.ts +279 -0
  68. package/dist/patterns/invoke.d.ts.map +1 -0
  69. package/dist/patterns/invoke.js +581 -0
  70. package/dist/patterns/invoke.js.map +1 -0
  71. package/dist/patterns/saga.d.ts +391 -0
  72. package/dist/patterns/saga.d.ts.map +1 -0
  73. package/dist/patterns/saga.js +556 -0
  74. package/dist/patterns/saga.js.map +1 -0
  75. package/dist/patterns.d.ts +17 -0
  76. package/dist/patterns.d.ts.map +1 -0
  77. package/dist/patterns.js +17 -0
  78. package/dist/patterns.js.map +1 -0
  79. package/dist/rate-limit.d.ts +16 -0
  80. package/dist/rate-limit.d.ts.map +1 -0
  81. package/dist/rate-limit.js +15 -0
  82. package/dist/rate-limit.js.map +1 -0
  83. package/dist/secrets.d.ts +11 -0
  84. package/dist/secrets.d.ts.map +1 -0
  85. package/dist/secrets.js +10 -0
  86. package/dist/secrets.js.map +1 -0
  87. package/dist/testing/test-utils.d.ts +99 -0
  88. package/dist/testing/test-utils.d.ts.map +1 -0
  89. package/dist/testing/test-utils.js +153 -0
  90. package/dist/testing/test-utils.js.map +1 -0
  91. package/dist/testing.d.ts +10 -0
  92. package/dist/testing.d.ts.map +1 -0
  93. package/dist/testing.js +9 -0
  94. package/dist/testing.js.map +1 -0
  95. package/dist/ws/ws.d.ts +139 -0
  96. package/dist/ws/ws.d.ts.map +1 -0
  97. package/dist/ws/ws.js +294 -0
  98. package/dist/ws/ws.js.map +1 -0
  99. package/dist/ws.d.ts +5 -133
  100. package/dist/ws.d.ts.map +1 -1
  101. package/dist/ws.js +4 -291
  102. package/dist/ws.js.map +1 -1
  103. package/package.json +47 -5
  104. package/dist/adapter.d.ts.map +0 -1
  105. package/dist/adapter.js.map +0 -1
  106. package/dist/context.d.ts.map +0 -1
  107. package/dist/context.js.map +0 -1
  108. package/dist/errors.d.ts.map +0 -1
  109. package/dist/errors.js.map +0 -1
  110. package/dist/handler.d.ts.map +0 -1
  111. package/dist/handler.js.map +0 -1
  112. package/dist/logger.d.ts.map +0 -1
  113. package/dist/logger.js.map +0 -1
  114. package/dist/middleware.d.ts +0 -47
  115. package/dist/middleware.d.ts.map +0 -1
  116. package/dist/middleware.js +0 -147
  117. package/dist/middleware.js.map +0 -1
  118. package/dist/response.d.ts.map +0 -1
  119. package/dist/response.js.map +0 -1
  120. /package/dist/{adapter.d.ts → handler/adapter.d.ts} +0 -0
  121. /package/dist/{errors.d.ts → handler/errors.d.ts} +0 -0
  122. /package/dist/{response.d.ts → handler/response.d.ts} +0 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @venturekit/runtime/rate-limit
3
+ *
4
+ * DynamoDB-backed rate limit stores for production use.
5
+ * Requires @aws-sdk/client-dynamodb.
6
+ *
7
+ * For in-memory stores (local dev), use the core import:
8
+ * `import { createMemoryRateLimitStore } from '@venturekit/runtime'`
9
+ *
10
+ * Import via: `import { createDynamoDBRateLimitStore } from '@venturekit/runtime/rate-limit'`
11
+ */
12
+ export { createDynamoDBRateLimitStore, createDefaultRateLimiter, } from './middleware/rate-limit-store.js';
13
+ // Re-export memory store and presets for convenience
14
+ export { createMemoryRateLimitStore, RATE_LIMIT_PRESETS, } from './middleware/rate-limit-store.js';
15
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAM1C,qDAAqD;AACrD,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @venturekit/runtime/secrets
3
+ *
4
+ * SSM Parameter Store and Secrets Manager clients.
5
+ * Requires @aws-sdk/client-ssm or @aws-sdk/client-secrets-manager.
6
+ *
7
+ * Import via: `import { createSecretsClient } from '@venturekit/runtime/secrets'`
8
+ */
9
+ export { createSecretsClient, createMemorySecretProvider, } from './config/secrets.js';
10
+ export type { SecretStore, SecretProvider, SecretsClientOptions, SecretsClient, } from './config/secrets.js';
11
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,aAAa,GACd,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @venturekit/runtime/secrets
3
+ *
4
+ * SSM Parameter Store and Secrets Manager clients.
5
+ * Requires @aws-sdk/client-ssm or @aws-sdk/client-secrets-manager.
6
+ *
7
+ * Import via: `import { createSecretsClient } from '@venturekit/runtime/secrets'`
8
+ */
9
+ export { createSecretsClient, createMemorySecretProvider, } from './config/secrets.js';
10
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * VentureKit Test Utilities
3
+ *
4
+ * Helpers for testing VentureKit handlers without Lambda/API Gateway.
5
+ */
6
+ import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
7
+ import type { RequestContext, UserContext, TenantContext } from '../handler/context.js';
8
+ import { Logger } from '../logging/logger.js';
9
+ /**
10
+ * Options for creating a test event
11
+ */
12
+ export interface MockEventOptions {
13
+ method?: string;
14
+ path?: string;
15
+ body?: unknown;
16
+ headers?: Record<string, string>;
17
+ queryStringParameters?: Record<string, string>;
18
+ pathParameters?: Record<string, string>;
19
+ sourceIp?: string;
20
+ userAgent?: string;
21
+ /** JWT claims for authenticated requests */
22
+ claims?: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Create a mock API Gateway V2 event for testing
26
+ */
27
+ export declare function mockEvent(options?: MockEventOptions): APIGatewayProxyEventV2;
28
+ /**
29
+ * Create a mock Lambda context
30
+ */
31
+ export declare function mockLambdaContext(): Context;
32
+ /**
33
+ * Options for creating a test RequestContext
34
+ */
35
+ export interface MockContextOptions {
36
+ requestId?: string;
37
+ method?: string;
38
+ path?: string;
39
+ sourceIp?: string;
40
+ userAgent?: string;
41
+ locale?: string;
42
+ user?: Partial<UserContext> | null;
43
+ tenant?: Partial<TenantContext> | null;
44
+ queryParams?: Record<string, string | undefined>;
45
+ isInternal?: boolean;
46
+ invokeId?: string;
47
+ }
48
+ /**
49
+ * Create a mock RequestContext for testing
50
+ */
51
+ export declare function mockContext(options?: MockContextOptions): RequestContext;
52
+ /**
53
+ * Log entry captured by mockLogger
54
+ */
55
+ export interface CapturedLog {
56
+ level: 'debug' | 'info' | 'warn' | 'error';
57
+ message: string;
58
+ data?: Record<string, unknown>;
59
+ }
60
+ /**
61
+ * Create a mock Logger that captures log entries for assertions.
62
+ * Extends Logger to be type-compatible but silently captures logs.
63
+ */
64
+ export declare function mockLogger(): Logger & {
65
+ logs: CapturedLog[];
66
+ clear: () => void;
67
+ };
68
+ /**
69
+ * Options for createTestHandler
70
+ */
71
+ export interface TestInvokeOptions {
72
+ method?: string;
73
+ path?: string;
74
+ body?: unknown;
75
+ headers?: Record<string, string>;
76
+ queryStringParameters?: Record<string, string>;
77
+ pathParameters?: Record<string, string>;
78
+ claims?: Record<string, unknown>;
79
+ }
80
+ /**
81
+ * Create a test wrapper for a VentureKit handler.
82
+ * Allows invoking the handler without a real Lambda environment.
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * import { handler } from '@venturekit/runtime';
87
+ * import { createTestHandler } from '@venturekit/runtime/test-utils';
88
+ *
89
+ * const myHandler = handler(async (body, ctx, log) => {
90
+ * return { hello: 'world' };
91
+ * });
92
+ *
93
+ * const invoke = createTestHandler(myHandler);
94
+ * const res = await invoke({ method: 'GET', path: '/hello' });
95
+ * expect(res.statusCode).toBe(200);
96
+ * ```
97
+ */
98
+ export declare function createTestHandler(lambdaHandler: (event: APIGatewayProxyEventV2, context: Context) => Promise<APIGatewayProxyResultV2>): (options?: TestInvokeOptions) => Promise<APIGatewayProxyResultV2>;
99
+ //# sourceMappingURL=test-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/testing/test-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * VentureKit Test Utilities
3
+ *
4
+ * Helpers for testing VentureKit handlers without Lambda/API Gateway.
5
+ */
6
+ import { Logger } from '../logging/logger.js';
7
+ /**
8
+ * Create a mock API Gateway V2 event for testing
9
+ */
10
+ export function mockEvent(options = {}) {
11
+ const { method = 'GET', path = '/test', body, headers = {}, queryStringParameters, pathParameters, sourceIp = '127.0.0.1', userAgent = 'vitest', claims, } = options;
12
+ const event = {
13
+ version: '2.0',
14
+ routeKey: `${method} ${path}`,
15
+ rawPath: path,
16
+ rawQueryString: queryStringParameters
17
+ ? Object.entries(queryStringParameters).map(([k, v]) => `${k}=${v}`).join('&')
18
+ : '',
19
+ headers: {
20
+ 'content-type': 'application/json',
21
+ 'user-agent': userAgent,
22
+ ...headers,
23
+ },
24
+ requestContext: {
25
+ accountId: '123456789012',
26
+ apiId: 'testapi',
27
+ domainName: 'localhost',
28
+ domainPrefix: 'localhost',
29
+ http: {
30
+ method,
31
+ path,
32
+ protocol: 'HTTP/1.1',
33
+ sourceIp,
34
+ userAgent,
35
+ },
36
+ requestId: `test-${Date.now()}`,
37
+ routeKey: `${method} ${path}`,
38
+ stage: '$default',
39
+ time: new Date().toISOString(),
40
+ timeEpoch: Date.now(),
41
+ ...(claims ? {
42
+ authorizer: {
43
+ jwt: { claims, scopes: [] },
44
+ },
45
+ } : {}),
46
+ },
47
+ body: body !== undefined ? JSON.stringify(body) : undefined,
48
+ isBase64Encoded: false,
49
+ };
50
+ if (queryStringParameters) {
51
+ event.queryStringParameters = queryStringParameters;
52
+ }
53
+ if (pathParameters) {
54
+ event.pathParameters = pathParameters;
55
+ }
56
+ return event;
57
+ }
58
+ /**
59
+ * Create a mock Lambda context
60
+ */
61
+ export function mockLambdaContext() {
62
+ return {
63
+ callbackWaitsForEmptyEventLoop: true,
64
+ functionName: 'test-function',
65
+ functionVersion: '$LATEST',
66
+ invokedFunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:test-function',
67
+ memoryLimitInMB: '128',
68
+ awsRequestId: `test-${Date.now()}`,
69
+ logGroupName: '/aws/lambda/test-function',
70
+ logStreamName: '2026/01/01/[$LATEST]test',
71
+ getRemainingTimeInMillis: () => 30000,
72
+ done: () => { },
73
+ fail: () => { },
74
+ succeed: () => { },
75
+ };
76
+ }
77
+ /**
78
+ * Create a mock RequestContext for testing
79
+ */
80
+ export function mockContext(options = {}) {
81
+ const user = options.user === null ? null : options.user ? {
82
+ id: options.user.id ?? 'test-user',
83
+ email: options.user.email,
84
+ scopes: options.user.scopes ?? [],
85
+ claims: options.user.claims ?? {},
86
+ } : null;
87
+ const tenant = options.tenant === null ? null : options.tenant ? {
88
+ id: options.tenant.id ?? 'test-tenant',
89
+ slug: options.tenant.slug,
90
+ metadata: options.tenant.metadata ?? {},
91
+ } : null;
92
+ return {
93
+ requestId: options.requestId ?? `test-${Date.now()}`,
94
+ timestamp: new Date(),
95
+ method: options.method ?? 'GET',
96
+ path: options.path ?? '/test',
97
+ sourceIp: options.sourceIp ?? '127.0.0.1',
98
+ userAgent: options.userAgent ?? 'vitest',
99
+ user,
100
+ tenant,
101
+ locale: options.locale ?? 'en',
102
+ rawEvent: mockEvent({ method: options.method, path: options.path }),
103
+ queryParams: options.queryParams,
104
+ isInternal: options.isInternal ?? false,
105
+ invokeId: options.invokeId,
106
+ };
107
+ }
108
+ /**
109
+ * Create a mock Logger that captures log entries for assertions.
110
+ * Extends Logger to be type-compatible but silently captures logs.
111
+ */
112
+ export function mockLogger() {
113
+ const logs = [];
114
+ const loggerInstance = new Logger({ minLevel: 'debug' });
115
+ // Override methods to capture logs silently
116
+ const capture = (level) => (message, data) => {
117
+ logs.push({ level, message, data });
118
+ };
119
+ loggerInstance.debug = capture('debug');
120
+ loggerInstance.info = capture('info');
121
+ loggerInstance.warn = capture('warn');
122
+ loggerInstance.error = capture('error');
123
+ return Object.assign(loggerInstance, {
124
+ logs,
125
+ clear: () => { logs.length = 0; },
126
+ });
127
+ }
128
+ /**
129
+ * Create a test wrapper for a VentureKit handler.
130
+ * Allows invoking the handler without a real Lambda environment.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * import { handler } from '@venturekit/runtime';
135
+ * import { createTestHandler } from '@venturekit/runtime/test-utils';
136
+ *
137
+ * const myHandler = handler(async (body, ctx, log) => {
138
+ * return { hello: 'world' };
139
+ * });
140
+ *
141
+ * const invoke = createTestHandler(myHandler);
142
+ * const res = await invoke({ method: 'GET', path: '/hello' });
143
+ * expect(res.statusCode).toBe(200);
144
+ * ```
145
+ */
146
+ export function createTestHandler(lambdaHandler) {
147
+ return async (options = {}) => {
148
+ const event = mockEvent(options);
149
+ const context = mockLambdaContext();
150
+ return lambdaHandler(event, context);
151
+ };
152
+ }
153
+ //# sourceMappingURL=test-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/testing/test-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @venturekit/runtime/testing
3
+ *
4
+ * Test utilities for VentureKit handlers.
5
+ *
6
+ * Import via: `import { mockEvent, mockContext } from '@venturekit/runtime/testing'`
7
+ */
8
+ export { mockEvent, mockLambdaContext, mockContext, mockLogger, createTestHandler, } from './testing/test-utils.js';
9
+ export type { MockEventOptions, MockContextOptions, TestInvokeOptions, CapturedLog, } from './testing/test-utils.js';
10
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,GACZ,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @venturekit/runtime/testing
3
+ *
4
+ * Test utilities for VentureKit handlers.
5
+ *
6
+ * Import via: `import { mockEvent, mockContext } from '@venturekit/runtime/testing'`
7
+ */
8
+ export { mockEvent, mockLambdaContext, mockContext, mockLogger, createTestHandler, } from './testing/test-utils.js';
9
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * WebSocket Connection Store
3
+ *
4
+ * DynamoDB-backed connection management for API Gateway WebSocket APIs.
5
+ *
6
+ * Authentication:
7
+ * Two-phase auth — the client connects without credentials, then sends
8
+ * an { action: "auth", token: "<jwt>" } message over the encrypted channel.
9
+ * The connection is stored as unauthenticated on $connect and upgraded
10
+ * to authenticated via connectionStore.authenticate().
11
+ * This avoids leaking JWTs in query strings, server logs, and access logs.
12
+ *
13
+ * Multi-tenancy:
14
+ * If enabled, each connection stores a tenantId alongside userId.
15
+ * Use sendToTenant() to broadcast within a tenant boundary.
16
+ *
17
+ * API:
18
+ * connectionStore.save(connectionId) — $connect (unauthenticated)
19
+ * connectionStore.authenticate(connectionId, metadata) — after JWT verification
20
+ * connectionStore.remove(connectionId) — $disconnect
21
+ * connectionStore.get(connectionId) — single connection
22
+ * connectionStore.getAll() — all connections
23
+ * connectionStore.getByUser(userId) — by user (GSI)
24
+ * connectionStore.getByTenant(tenantId) — by tenant (GSI)
25
+ * connectionStore.postToConnection(domain, stage, id, data) — send to one
26
+ * connectionStore.sendToUser(domain, stage, userId, data) — send to all user sessions
27
+ * connectionStore.sendToTenant(domain, stage, tenantId, data) — broadcast within tenant
28
+ * connectionStore.broadcast(domain, stage, data) — broadcast to all
29
+ *
30
+ * Environment variables:
31
+ * CONNECTIONS_TABLE — DynamoDB table name (required)
32
+ *
33
+ * DynamoDB table schema:
34
+ * Partition key: connectionId (String)
35
+ * TTL attribute: ttl
36
+ * GSI: userId-index (partition key: userId)
37
+ * GSI: tenantId-index (partition key: tenantId) — only if multi-tenancy enabled
38
+ */
39
+ export interface ConnectionRecord {
40
+ connectionId: string;
41
+ authenticated: boolean;
42
+ userId?: string;
43
+ tenantId?: string;
44
+ email?: string;
45
+ connectedAt: number;
46
+ authenticatedAt?: number;
47
+ ttl: number;
48
+ [key: string]: unknown;
49
+ }
50
+ export interface ConnectionMetadata {
51
+ userId: string;
52
+ tenantId?: string;
53
+ email?: string;
54
+ [key: string]: unknown;
55
+ }
56
+ /**
57
+ * WebSocket connection store backed by DynamoDB.
58
+ *
59
+ * Two-phase authentication flow:
60
+ *
61
+ * 1. $connect handler:
62
+ * ```typescript
63
+ * await connectionStore.save(connectionId);
64
+ * // Connection is unauthenticated, TTL = 30s
65
+ * ```
66
+ *
67
+ * 2. Client sends auth message over the encrypted WebSocket:
68
+ * ```json
69
+ * { "action": "auth", "token": "<jwt>" }
70
+ * ```
71
+ *
72
+ * 3. $default handler verifies JWT, then:
73
+ * ```typescript
74
+ * await connectionStore.authenticate(connectionId, { userId, tenantId, email });
75
+ * // Connection is now authenticated, TTL extended to 2h
76
+ * ```
77
+ */
78
+ export declare const connectionStore: {
79
+ /**
80
+ * Save a new connection on $connect.
81
+ * The connection is unauthenticated with a short TTL.
82
+ * The client must send an auth message to upgrade.
83
+ */
84
+ save(connectionId: string): Promise<void>;
85
+ /**
86
+ * Authenticate a connection after JWT verification.
87
+ * Updates the record with user metadata and extends the TTL.
88
+ *
89
+ * @param connectionId — the connection to authenticate
90
+ * @param metadata — must include userId, optionally tenantId, email, etc.
91
+ */
92
+ authenticate(connectionId: string, metadata: ConnectionMetadata): Promise<void>;
93
+ /**
94
+ * Remove a connection on $disconnect.
95
+ */
96
+ remove(connectionId: string): Promise<void>;
97
+ /**
98
+ * Get a single connection record.
99
+ */
100
+ get(connectionId: string): Promise<ConnectionRecord | null>;
101
+ /**
102
+ * Get all authenticated connections.
103
+ * For large-scale apps, prefer getByUser() or getByTenant().
104
+ */
105
+ getAll(): Promise<ConnectionRecord[]>;
106
+ /**
107
+ * Get all connections for a specific user.
108
+ * A user can have multiple active connections (e.g. multiple tabs/devices).
109
+ * Requires GSI: userId-index (partition key: userId).
110
+ */
111
+ getByUser(userId: string): Promise<ConnectionRecord[]>;
112
+ /**
113
+ * Get all connections for a specific tenant.
114
+ * Requires GSI: tenantId-index (partition key: tenantId).
115
+ */
116
+ getByTenant(tenantId: string): Promise<ConnectionRecord[]>;
117
+ /**
118
+ * Send data to a specific connection via API Gateway Management API.
119
+ * Automatically cleans up stale connections (GoneException).
120
+ * Returns true if sent, false if the connection was stale and removed.
121
+ */
122
+ postToConnection(domainName: string, stage: string, connectionId: string, data: unknown): Promise<boolean>;
123
+ /**
124
+ * Send data to all connections belonging to a specific user.
125
+ * Returns the number of connections that received the message.
126
+ */
127
+ sendToUser(domainName: string, stage: string, userId: string, data: unknown): Promise<number>;
128
+ /**
129
+ * Send data to all connections within a specific tenant.
130
+ * Returns the number of connections that received the message.
131
+ */
132
+ sendToTenant(domainName: string, stage: string, tenantId: string, data: unknown): Promise<number>;
133
+ /**
134
+ * Broadcast data to all authenticated connections.
135
+ * Returns the number of clients that received the message.
136
+ */
137
+ broadcast(domainName: string, stage: string, data: unknown): Promise<number>;
138
+ };
139
+ //# sourceMappingURL=ws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/ws/ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA4DD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe;IAC1B;;;;OAIG;uBACsB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/C;;;;;;OAMG;+BAC8B,MAAM,YAAY,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoDrF;;OAEG;yBACwB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD;;OAEG;sBACqB,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAUjE;;;OAGG;cACa,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAW3C;;;;OAIG;sBACqB,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAY5D;;;OAGG;0BACyB,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAYhE;;;;OAIG;iCAEW,MAAM,SACX,MAAM,gBACC,MAAM,QACd,OAAO,GACZ,OAAO,CAAC,OAAO,CAAC;IAqBnB;;;OAGG;2BAEW,MAAM,SACX,MAAM,UACL,MAAM,QACR,OAAO,GACZ,OAAO,CAAC,MAAM,CAAC;IAKlB;;;OAGG;6BAEW,MAAM,SACX,MAAM,YACH,MAAM,QACV,OAAO,GACZ,OAAO,CAAC,MAAM,CAAC;IAKlB;;;OAGG;0BACyB,MAAM,SAAS,MAAM,QAAQ,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;CAInF,CAAC"}