ioredis-toolkit 0.0.9 → 0.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/CHANGELOG.md +67 -0
- package/LICENSE +1 -1
- package/README.md +68 -1058
- package/dist/cache/cache.d.ts +30 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +59 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/config.d.ts +12 -0
- package/dist/cache/config.d.ts.map +1 -0
- package/dist/cache/config.js +13 -0
- package/dist/cache/config.js.map +1 -0
- package/dist/cache/types.d.ts +32 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +5 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/index.d.ts +43 -51
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -44
- package/dist/index.js.map +1 -0
- package/dist/lock/config.d.ts +12 -0
- package/dist/lock/config.d.ts.map +1 -0
- package/dist/lock/config.js +8 -0
- package/dist/lock/config.js.map +1 -0
- package/dist/lock/lock.d.ts +20 -0
- package/dist/lock/lock.d.ts.map +1 -0
- package/dist/lock/lock.js +44 -0
- package/dist/lock/lock.js.map +1 -0
- package/dist/lock/types.d.ts +19 -0
- package/dist/lock/types.d.ts.map +1 -0
- package/dist/lock/types.js +2 -0
- package/dist/lock/types.js.map +1 -0
- package/dist/modules-config.d.ts +3 -0
- package/dist/modules-config.d.ts.map +1 -0
- package/dist/modules-config.js +2 -0
- package/dist/modules-config.js.map +1 -0
- package/dist/pubsub/config.d.ts +11 -0
- package/dist/pubsub/config.d.ts.map +1 -0
- package/dist/pubsub/config.js +6 -0
- package/dist/pubsub/config.js.map +1 -0
- package/dist/pubsub/pubsub.d.ts +20 -0
- package/dist/pubsub/pubsub.d.ts.map +1 -0
- package/dist/pubsub/pubsub.js +54 -0
- package/dist/pubsub/pubsub.js.map +1 -0
- package/dist/pubsub/types.d.ts +24 -0
- package/dist/pubsub/types.d.ts.map +1 -0
- package/dist/pubsub/types.js +2 -0
- package/dist/pubsub/types.js.map +1 -0
- package/dist/rate-limit/config.d.ts +12 -0
- package/dist/rate-limit/config.d.ts.map +1 -0
- package/dist/rate-limit/config.js +6 -0
- package/dist/rate-limit/config.js.map +1 -0
- package/dist/rate-limit/rate-limiter.d.ts +18 -0
- package/dist/rate-limit/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limit/rate-limiter.js +37 -0
- package/dist/rate-limit/rate-limiter.js.map +1 -0
- package/dist/rate-limit/types.d.ts +27 -0
- package/dist/rate-limit/types.d.ts.map +1 -0
- package/dist/rate-limit/types.js +2 -0
- package/dist/rate-limit/types.js.map +1 -0
- package/dist/redis/client-facade.d.ts +77 -0
- package/dist/redis/client-facade.d.ts.map +1 -0
- package/dist/redis/client-facade.js +102 -0
- package/dist/redis/client-facade.js.map +1 -0
- package/dist/redis/client.d.ts +10 -0
- package/dist/redis/client.d.ts.map +1 -0
- package/dist/redis/client.js +29 -0
- package/dist/redis/client.js.map +1 -0
- package/dist/redis/cluster.d.ts +7 -0
- package/dist/redis/cluster.d.ts.map +1 -0
- package/dist/redis/cluster.js +47 -0
- package/dist/redis/cluster.js.map +1 -0
- package/dist/redis/config.d.ts +39 -0
- package/dist/redis/config.d.ts.map +1 -0
- package/dist/redis/config.js +52 -0
- package/dist/redis/config.js.map +1 -0
- package/dist/redis/errors.d.ts +5 -0
- package/dist/redis/errors.d.ts.map +1 -0
- package/dist/redis/errors.js +5 -0
- package/dist/redis/errors.js.map +1 -0
- package/dist/redis/types.d.ts +135 -0
- package/dist/redis/types.d.ts.map +1 -0
- package/dist/redis/types.js +2 -0
- package/dist/redis/types.js.map +1 -0
- package/dist/redis/wrapper.d.ts +88 -0
- package/dist/redis/wrapper.d.ts.map +1 -0
- package/dist/redis/wrapper.js +206 -0
- package/dist/redis/wrapper.js.map +1 -0
- package/dist/session/config.d.ts +47 -0
- package/dist/session/config.d.ts.map +1 -0
- package/dist/session/config.js +101 -0
- package/dist/session/config.js.map +1 -0
- package/dist/session/cookie.d.ts +16 -0
- package/dist/session/cookie.d.ts.map +1 -0
- package/dist/session/cookie.js +28 -0
- package/dist/session/cookie.js.map +1 -0
- package/dist/session/errors.d.ts +56 -0
- package/dist/session/errors.d.ts.map +1 -0
- package/dist/session/errors.js +58 -0
- package/dist/session/errors.js.map +1 -0
- package/dist/session/factory.d.ts +21 -0
- package/dist/session/factory.d.ts.map +1 -0
- package/dist/session/factory.js +30 -0
- package/dist/session/factory.js.map +1 -0
- package/dist/session/health.d.ts +12 -0
- package/dist/session/health.d.ts.map +1 -0
- package/dist/session/health.js +23 -0
- package/dist/session/health.js.map +1 -0
- package/dist/session/keys.d.ts +23 -0
- package/dist/session/keys.d.ts.map +1 -0
- package/dist/session/keys.js +27 -0
- package/dist/session/keys.js.map +1 -0
- package/dist/session/manager.d.ts +34 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +31 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/metrics.d.ts +11 -0
- package/dist/session/metrics.d.ts.map +1 -0
- package/dist/session/metrics.js +10 -0
- package/dist/session/metrics.js.map +1 -0
- package/dist/session/repository.d.ts +49 -0
- package/dist/session/repository.d.ts.map +1 -0
- package/dist/session/repository.js +203 -0
- package/dist/session/repository.js.map +1 -0
- package/dist/session/revocation.d.ts +22 -0
- package/dist/session/revocation.d.ts.map +1 -0
- package/dist/session/revocation.js +41 -0
- package/dist/session/revocation.js.map +1 -0
- package/dist/session/script-sources.d.ts +11 -0
- package/dist/session/script-sources.d.ts.map +1 -0
- package/dist/session/script-sources.js +140 -0
- package/dist/session/script-sources.js.map +1 -0
- package/dist/session/scripts.d.ts +15 -0
- package/dist/session/scripts.d.ts.map +1 -0
- package/dist/session/scripts.js +41 -0
- package/dist/session/scripts.js.map +1 -0
- package/dist/session/serializer.d.ts +12 -0
- package/dist/session/serializer.d.ts.map +1 -0
- package/dist/session/serializer.js +77 -0
- package/dist/session/serializer.js.map +1 -0
- package/dist/session/service.d.ts +48 -0
- package/dist/session/service.d.ts.map +1 -0
- package/dist/session/service.js +235 -0
- package/dist/session/service.js.map +1 -0
- package/dist/session/token.d.ts +16 -0
- package/dist/session/token.d.ts.map +1 -0
- package/dist/session/token.js +32 -0
- package/dist/session/token.js.map +1 -0
- package/dist/session/types.d.ts +134 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +2 -0
- package/dist/session/types.js.map +1 -0
- package/dist/streams/config.d.ts +12 -0
- package/dist/streams/config.d.ts.map +1 -0
- package/dist/streams/config.js +6 -0
- package/dist/streams/config.js.map +1 -0
- package/dist/streams/streams.d.ts +24 -0
- package/dist/streams/streams.d.ts.map +1 -0
- package/dist/streams/streams.js +55 -0
- package/dist/streams/streams.js.map +1 -0
- package/dist/streams/types.d.ts +32 -0
- package/dist/streams/types.d.ts.map +1 -0
- package/dist/streams/types.js +2 -0
- package/dist/streams/types.js.map +1 -0
- package/docs/ACCEPTANCE-REPORT.md +70 -0
- package/docs/ARCHITECTURE.md +61 -0
- package/docs/CAPACITY.md +33 -0
- package/docs/DEPLOYMENT.md +22 -0
- package/docs/README-API.md +15 -0
- package/docs/STATE-MACHINE.md +38 -0
- package/docs/TESTING.md +37 -0
- package/docs/THREAT-MODEL.md +23 -0
- package/docs/TYPE-SAFETY.md +34 -0
- package/docs/modules/cache/README.md +7 -0
- package/docs/modules/cache/usage.md +156 -0
- package/docs/modules/lock/README.md +7 -0
- package/docs/modules/lock/usage.md +105 -0
- package/docs/modules/pubsub/README.md +7 -0
- package/docs/modules/pubsub/usage.md +106 -0
- package/docs/modules/rate-limit/README.md +7 -0
- package/docs/modules/rate-limit/usage.md +100 -0
- package/docs/modules/sessions/README.md +7 -0
- package/docs/modules/sessions/usage.md +262 -0
- package/docs/modules/streams/README.md +7 -0
- package/docs/modules/streams/usage.md +141 -0
- package/package.json +50 -60
- package/src/scripts/cleanup-index.lua +4 -0
- package/src/scripts/conditional-update.lua +21 -0
- package/src/scripts/consume-session.lua +21 -0
- package/src/scripts/create-session.lua +28 -0
- package/src/scripts/delete.lua +2 -0
- package/src/scripts/destroy-user.lua +13 -0
- package/src/scripts/enforce-limit.lua +17 -0
- package/src/scripts/revoke-session.lua +13 -0
- package/src/scripts/rotate.lua +24 -0
- package/src/scripts/touch-session.lua +28 -0
- package/src/scripts/update-session.lua +18 -0
- package/dist/cache.d.ts +0 -796
- package/dist/cache.js +0 -1120
- package/dist/client.d.ts +0 -284
- package/dist/client.js +0 -1114
- package/dist/cluster-slot.d.ts +0 -4
- package/dist/cluster-slot.js +0 -31
- package/dist/cluster.d.ts +0 -79
- package/dist/cluster.js +0 -156
- package/dist/errors.d.ts +0 -30
- package/dist/errors.js +0 -63
- package/dist/health.d.ts +0 -180
- package/dist/health.js +0 -239
- package/dist/lock.d.ts +0 -248
- package/dist/lock.js +0 -397
- package/dist/logger.d.ts +0 -12
- package/dist/logger.js +0 -40
- package/dist/pubsub.d.ts +0 -423
- package/dist/pubsub.js +0 -537
- package/dist/ratelimiter.d.ts +0 -441
- package/dist/ratelimiter.js +0 -539
- package/dist/session/index.d.ts +0 -23
- package/dist/session/index.js +0 -16
- package/dist/session/revocation-store.d.ts +0 -176
- package/dist/session/revocation-store.js +0 -318
- package/dist/session/scripts/cleanup-index.lua +0 -21
- package/dist/session/scripts/conditional-update-encrypted.lua +0 -60
- package/dist/session/scripts/conditional-update.lua +0 -63
- package/dist/session/scripts/create.lua +0 -83
- package/dist/session/scripts/delete-by-user.lua +0 -29
- package/dist/session/scripts/delete.lua +0 -15
- package/dist/session/scripts/enforce-limit.lua +0 -38
- package/dist/session/scripts/revoke.lua +0 -61
- package/dist/session/scripts/rotate-encrypted.lua +0 -110
- package/dist/session/scripts/rotate.lua +0 -122
- package/dist/session/scripts/touch-encrypted.lua +0 -89
- package/dist/session/scripts/touch.lua +0 -72
- package/dist/session/scripts/validate.lua +0 -90
- package/dist/session/session-circuit-breaker.d.ts +0 -42
- package/dist/session/session-circuit-breaker.js +0 -129
- package/dist/session/session-config.d.ts +0 -335
- package/dist/session/session-config.js +0 -162
- package/dist/session/session-cookie.d.ts +0 -72
- package/dist/session/session-cookie.js +0 -101
- package/dist/session/session-encryption.d.ts +0 -87
- package/dist/session/session-encryption.js +0 -139
- package/dist/session/session-errors.d.ts +0 -85
- package/dist/session/session-errors.js +0 -145
- package/dist/session/session-health.d.ts +0 -38
- package/dist/session/session-health.js +0 -60
- package/dist/session/session-keys.d.ts +0 -51
- package/dist/session/session-keys.js +0 -113
- package/dist/session/session-manager.d.ts +0 -73
- package/dist/session/session-manager.js +0 -94
- package/dist/session/session-metrics.d.ts +0 -33
- package/dist/session/session-metrics.js +0 -112
- package/dist/session/session-repository.d.ts +0 -161
- package/dist/session/session-repository.js +0 -683
- package/dist/session/session-scripts.d.ts +0 -36
- package/dist/session/session-scripts.js +0 -130
- package/dist/session/session-serializer.d.ts +0 -42
- package/dist/session/session-serializer.js +0 -248
- package/dist/session/session-service.d.ts +0 -104
- package/dist/session/session-service.js +0 -611
- package/dist/session/session-token.d.ts +0 -38
- package/dist/session/session-token.js +0 -86
- package/dist/session/session-types.d.ts +0 -253
- package/dist/session/session-types.js +0 -16
- package/dist/types.d.ts +0 -924
- package/dist/types.js +0 -151
- package/dist/utils/deepmerge.d.ts +0 -9
- package/dist/utils/deepmerge.js +0 -61
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SessionConfigurationError } from "./errors.js";
|
|
3
|
+
/** Runtime schema for session configuration and security invariants. */
|
|
4
|
+
export const SessionConfigSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
enabled: z.boolean().default(false),
|
|
7
|
+
namespace: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.max(128)
|
|
11
|
+
.regex(/^[A-Za-z0-9:_-]+$/)
|
|
12
|
+
.default("app"),
|
|
13
|
+
tokenBytes: z.number().int().min(32).max(128).default(32),
|
|
14
|
+
ttl: z
|
|
15
|
+
.number()
|
|
16
|
+
.int()
|
|
17
|
+
.positive()
|
|
18
|
+
.default(60 * 60 * 24 * 30),
|
|
19
|
+
idleTimeout: z.number().int().positive().optional(),
|
|
20
|
+
absoluteTimeout: z.number().int().positive().optional(),
|
|
21
|
+
touchInterval: z.number().int().nonnegative().default(60),
|
|
22
|
+
rolling: z.boolean().default(true),
|
|
23
|
+
securityVersionEnabled: z.boolean().default(false),
|
|
24
|
+
maxSessionsPerUser: z.number().int().nonnegative().max(1_000).default(20),
|
|
25
|
+
maxMetadataBytes: z
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.positive()
|
|
29
|
+
.max(64 * 1024)
|
|
30
|
+
.default(8 * 1024),
|
|
31
|
+
maxBatchSize: z.number().int().positive().max(1_000).default(200),
|
|
32
|
+
maxConcurrency: z.number().int().positive().max(64).default(8),
|
|
33
|
+
storeIpAddress: z.boolean().default(false),
|
|
34
|
+
storeUserAgent: z.boolean().default(false),
|
|
35
|
+
storeDeviceId: z.boolean().default(false),
|
|
36
|
+
encryption: z
|
|
37
|
+
.object({ enabled: z.boolean().default(false) })
|
|
38
|
+
.default({ enabled: false }),
|
|
39
|
+
circuitBreaker: z
|
|
40
|
+
.object({
|
|
41
|
+
enabled: z.boolean().default(false),
|
|
42
|
+
failureThreshold: z.number().int().positive().default(5),
|
|
43
|
+
resetTimeoutMs: z.number().int().positive().default(10_000),
|
|
44
|
+
halfOpenMaxRequests: z.number().int().positive().default(1),
|
|
45
|
+
})
|
|
46
|
+
.default({
|
|
47
|
+
enabled: false,
|
|
48
|
+
failureThreshold: 5,
|
|
49
|
+
resetTimeoutMs: 10_000,
|
|
50
|
+
halfOpenMaxRequests: 1,
|
|
51
|
+
}),
|
|
52
|
+
cookie: z
|
|
53
|
+
.object({
|
|
54
|
+
name: z.string().min(1).max(256).default("session"),
|
|
55
|
+
httpOnly: z.boolean().default(true),
|
|
56
|
+
secure: z.boolean().default(true),
|
|
57
|
+
sameSite: z.enum(["strict", "lax", "none"]).default("lax"),
|
|
58
|
+
domain: z.string().optional(),
|
|
59
|
+
path: z.string().default("/"),
|
|
60
|
+
maxAge: z.number().int().positive().optional(),
|
|
61
|
+
})
|
|
62
|
+
.default({
|
|
63
|
+
name: "session",
|
|
64
|
+
httpOnly: true,
|
|
65
|
+
secure: true,
|
|
66
|
+
sameSite: "lax",
|
|
67
|
+
path: "/",
|
|
68
|
+
}),
|
|
69
|
+
})
|
|
70
|
+
.superRefine((c, ctx) => {
|
|
71
|
+
if (c.absoluteTimeout !== undefined &&
|
|
72
|
+
c.idleTimeout !== undefined &&
|
|
73
|
+
c.idleTimeout > c.absoluteTimeout)
|
|
74
|
+
ctx.addIssue({
|
|
75
|
+
code: "custom",
|
|
76
|
+
path: ["idleTimeout"],
|
|
77
|
+
message: "idleTimeout must not exceed absoluteTimeout",
|
|
78
|
+
});
|
|
79
|
+
if (c.absoluteTimeout !== undefined && c.ttl > c.absoluteTimeout)
|
|
80
|
+
ctx.addIssue({
|
|
81
|
+
code: "custom",
|
|
82
|
+
path: ["ttl"],
|
|
83
|
+
message: "ttl must not exceed absoluteTimeout",
|
|
84
|
+
});
|
|
85
|
+
if (c.cookie.sameSite === "none" && !c.cookie.secure)
|
|
86
|
+
ctx.addIssue({
|
|
87
|
+
code: "custom",
|
|
88
|
+
path: ["cookie", "secure"],
|
|
89
|
+
message: "SameSite=None requires Secure",
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
/** Validates and applies secure defaults to session configuration. */
|
|
93
|
+
export function parseSessionConfig(input) {
|
|
94
|
+
const result = SessionConfigSchema.safeParse(input ?? {});
|
|
95
|
+
if (!result.success)
|
|
96
|
+
throw new SessionConfigurationError(result.error.issues
|
|
97
|
+
.map((i) => `${i.path.join(".")}: ${i.message}`)
|
|
98
|
+
.join("; "));
|
|
99
|
+
return result.data;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/session/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Options used to serialize a Set-Cookie header. Values are intentionally narrow to avoid malformed headers. */
|
|
2
|
+
export interface CookieOptions {
|
|
3
|
+
name: string;
|
|
4
|
+
httpOnly?: boolean;
|
|
5
|
+
secure?: boolean;
|
|
6
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
7
|
+
domain?: string;
|
|
8
|
+
path?: string;
|
|
9
|
+
maxAge?: number;
|
|
10
|
+
expires?: Date;
|
|
11
|
+
}
|
|
12
|
+
/** Serializes a cookie value and options into a Set-Cookie-compatible header value. */
|
|
13
|
+
export declare function serializeCookie(value: string, options: CookieOptions): string;
|
|
14
|
+
/** Serializes an expired cookie that instructs a browser to remove the named cookie. */
|
|
15
|
+
export declare function serializeDeletionCookie(options: CookieOptions): string;
|
|
16
|
+
//# sourceMappingURL=cookie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/session/cookie.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAC;CAAE;AAC7L,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAe7E;AACD,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAiF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Serializes a cookie value and options into a Set-Cookie-compatible header value. */
|
|
2
|
+
export function serializeCookie(value, options) {
|
|
3
|
+
if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(options.name))
|
|
4
|
+
throw new Error('Invalid cookie name');
|
|
5
|
+
if (options.sameSite === 'none' && options.secure === false)
|
|
6
|
+
throw new Error('SameSite=None requires Secure');
|
|
7
|
+
// options.name is validated against the RFC 6265 cookie-name token charset above, so it is
|
|
8
|
+
// already header-safe and must be emitted as-is: encodeURIComponent would percent-encode
|
|
9
|
+
// several characters that charset permits (# $ & + ^ | ~), silently changing the cookie name.
|
|
10
|
+
const parts = [`${options.name}=${encodeURIComponent(value)}`];
|
|
11
|
+
if (options.maxAge !== undefined)
|
|
12
|
+
parts.push(`Max-Age=${Math.floor(options.maxAge)}`);
|
|
13
|
+
if (options.expires)
|
|
14
|
+
parts.push(`Expires=${options.expires.toUTCString()}`);
|
|
15
|
+
if (options.domain)
|
|
16
|
+
parts.push(`Domain=${options.domain}`);
|
|
17
|
+
parts.push(`Path=${options.path ?? '/'}`);
|
|
18
|
+
if (options.httpOnly !== false)
|
|
19
|
+
parts.push('HttpOnly');
|
|
20
|
+
if (options.secure !== false)
|
|
21
|
+
parts.push('Secure');
|
|
22
|
+
if (options.sameSite)
|
|
23
|
+
parts.push(`SameSite=${options.sameSite[0].toUpperCase()}${options.sameSite.slice(1)}`);
|
|
24
|
+
return parts.join('; ');
|
|
25
|
+
}
|
|
26
|
+
/** Serializes an expired cookie that instructs a browser to remove the named cookie. */
|
|
27
|
+
export function serializeDeletionCookie(options) { return serializeCookie('', { ...options, maxAge: 0, expires: new Date(0) }); }
|
|
28
|
+
//# sourceMappingURL=cookie.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/session/cookie.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,OAAsB;IACnE,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC9G,2FAA2F;IAC3F,yFAAyF;IACzF,8FAA8F;IAC9F,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtF,IAAI,OAAO,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/G,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AACD,wFAAwF;AACxF,MAAM,UAAU,uBAAuB,CAAC,OAAsB,IAAY,OAAO,eAAe,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Stable machine-readable error codes emitted by the session subsystem. */
|
|
2
|
+
export type SessionErrorCode = 'SESSION_NOT_FOUND' | 'SESSION_EXPIRED' | 'SESSION_REVOKED' | 'SESSION_INVALID' | 'SESSION_REPLAY' | 'SESSION_ROTATION' | 'SESSION_CONFLICT' | 'SESSION_STORAGE' | 'SESSION_SERIALIZATION' | 'SESSION_CONFIGURATION' | 'SESSION_INPUT' | 'SESSION_LIMIT';
|
|
3
|
+
/** Base typed error for session validation, lifecycle, storage, and configuration failures. */
|
|
4
|
+
export declare class SessionError extends Error {
|
|
5
|
+
readonly code: SessionErrorCode;
|
|
6
|
+
constructor(code: SessionErrorCode, message: string, options?: ErrorOptions);
|
|
7
|
+
}
|
|
8
|
+
/** Thrown when an authoritative session record cannot be found. */
|
|
9
|
+
export declare class SessionNotFoundError extends SessionError {
|
|
10
|
+
constructor();
|
|
11
|
+
}
|
|
12
|
+
/** Thrown when a session is outside its configured lifetime. */
|
|
13
|
+
export declare class SessionExpiredError extends SessionError {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
/** Thrown when a session has been explicitly revoked. */
|
|
17
|
+
export declare class SessionRevokedError extends SessionError {
|
|
18
|
+
constructor();
|
|
19
|
+
}
|
|
20
|
+
/** Thrown when session input or state fails validation. */
|
|
21
|
+
export declare class SessionInvalidError extends SessionError {
|
|
22
|
+
constructor();
|
|
23
|
+
}
|
|
24
|
+
/** Thrown when a consumed session credential is replayed. */
|
|
25
|
+
export declare class SessionReplayError extends SessionError {
|
|
26
|
+
constructor();
|
|
27
|
+
}
|
|
28
|
+
/** Thrown when rotation cannot complete safely. */
|
|
29
|
+
export declare class SessionRotationError extends SessionError {
|
|
30
|
+
constructor(message?: string, cause?: unknown);
|
|
31
|
+
}
|
|
32
|
+
/** Thrown when optimistic session concurrency detects a conflict. */
|
|
33
|
+
export declare class SessionConflictError extends SessionError {
|
|
34
|
+
constructor();
|
|
35
|
+
}
|
|
36
|
+
/** Thrown when Redis-backed session persistence cannot be completed or read. */
|
|
37
|
+
export declare class SessionStorageError extends SessionError {
|
|
38
|
+
constructor(message: string, cause?: unknown);
|
|
39
|
+
}
|
|
40
|
+
/** Thrown when a session envelope cannot be serialized or validated. */
|
|
41
|
+
export declare class SessionSerializationError extends SessionError {
|
|
42
|
+
constructor(message?: string, cause?: unknown);
|
|
43
|
+
}
|
|
44
|
+
/** Thrown when session configuration is invalid or incomplete. */
|
|
45
|
+
export declare class SessionConfigurationError extends SessionError {
|
|
46
|
+
constructor(message: string);
|
|
47
|
+
}
|
|
48
|
+
/** Thrown when token or other session input is malformed. */
|
|
49
|
+
export declare class SessionInputError extends SessionError {
|
|
50
|
+
constructor(message: string);
|
|
51
|
+
}
|
|
52
|
+
/** Thrown when a configured session limit prevents an operation. */
|
|
53
|
+
export declare class SessionLimitError extends SessionError {
|
|
54
|
+
constructor(message: string);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/session/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB,GAC/E,gBAAgB,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,iBAAiB,GAC9E,uBAAuB,GAAG,uBAAuB,GAAG,eAAe,GAAG,eAAe,CAAC;AAE1F,+FAA+F;AAC/F,qBAAa,YAAa,SAAQ,KAAK;aACT,IAAI,EAAE,gBAAgB;gBAAtB,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAG5F;AACD,mEAAmE;AACnE,qBAAa,oBAAqB,SAAQ,YAAY;;CAAuE;AAC7H,gEAAgE;AAChE,qBAAa,mBAAoB,SAAQ,YAAY;;CAAmE;AACxH,yDAAyD;AACzD,qBAAa,mBAAoB,SAAQ,YAAY;;CAAmE;AACxH,2DAA2D;AAC3D,qBAAa,mBAAoB,SAAQ,YAAY;;CAAmE;AACxH,6DAA6D;AAC7D,qBAAa,kBAAmB,SAAQ,YAAY;;CAA0E;AAC9H,mDAAmD;AACnD,qBAAa,oBAAqB,SAAQ,YAAY;gBAAe,OAAO,SAA4B,EAAE,KAAK,CAAC,EAAE,OAAO;CAAsD;AAC/K,qEAAqE;AACrE,qBAAa,oBAAqB,SAAQ,YAAY;;CAA6E;AACnI,gFAAgF;AAChF,qBAAa,mBAAoB,SAAQ,YAAY;gBAAe,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAAqD;AACzJ,wEAAwE;AACxE,qBAAa,yBAA0B,SAAQ,YAAY;gBAAe,OAAO,SAAiC,EAAE,KAAK,CAAC,EAAE,OAAO;CAA2D;AAC9L,kEAAkE;AAClE,qBAAa,yBAA0B,SAAQ,YAAY;gBAAe,OAAO,EAAE,MAAM;CAAgD;AACzI,6DAA6D;AAC7D,qBAAa,iBAAkB,SAAQ,YAAY;gBAAe,OAAO,EAAE,MAAM;CAAwC;AACzH,oEAAoE;AACpE,qBAAa,iBAAkB,SAAQ,YAAY;gBAAe,OAAO,EAAE,MAAM;CAAwC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Base typed error for session validation, lifecycle, storage, and configuration failures. */
|
|
2
|
+
export class SessionError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(code, message, options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.name = 'SessionError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Thrown when an authoritative session record cannot be found. */
|
|
11
|
+
export class SessionNotFoundError extends SessionError {
|
|
12
|
+
constructor() { super('SESSION_NOT_FOUND', 'Session not found'); }
|
|
13
|
+
}
|
|
14
|
+
/** Thrown when a session is outside its configured lifetime. */
|
|
15
|
+
export class SessionExpiredError extends SessionError {
|
|
16
|
+
constructor() { super('SESSION_EXPIRED', 'Session expired'); }
|
|
17
|
+
}
|
|
18
|
+
/** Thrown when a session has been explicitly revoked. */
|
|
19
|
+
export class SessionRevokedError extends SessionError {
|
|
20
|
+
constructor() { super('SESSION_REVOKED', 'Session revoked'); }
|
|
21
|
+
}
|
|
22
|
+
/** Thrown when session input or state fails validation. */
|
|
23
|
+
export class SessionInvalidError extends SessionError {
|
|
24
|
+
constructor() { super('SESSION_INVALID', 'Session invalid'); }
|
|
25
|
+
}
|
|
26
|
+
/** Thrown when a consumed session credential is replayed. */
|
|
27
|
+
export class SessionReplayError extends SessionError {
|
|
28
|
+
constructor() { super('SESSION_REPLAY', 'Session replay detected'); }
|
|
29
|
+
}
|
|
30
|
+
/** Thrown when rotation cannot complete safely. */
|
|
31
|
+
export class SessionRotationError extends SessionError {
|
|
32
|
+
constructor(message = 'Session rotation failed', cause) { super('SESSION_ROTATION', message, { cause }); }
|
|
33
|
+
}
|
|
34
|
+
/** Thrown when optimistic session concurrency detects a conflict. */
|
|
35
|
+
export class SessionConflictError extends SessionError {
|
|
36
|
+
constructor() { super('SESSION_CONFLICT', 'Session version conflict'); }
|
|
37
|
+
}
|
|
38
|
+
/** Thrown when Redis-backed session persistence cannot be completed or read. */
|
|
39
|
+
export class SessionStorageError extends SessionError {
|
|
40
|
+
constructor(message, cause) { super('SESSION_STORAGE', message, { cause }); }
|
|
41
|
+
}
|
|
42
|
+
/** Thrown when a session envelope cannot be serialized or validated. */
|
|
43
|
+
export class SessionSerializationError extends SessionError {
|
|
44
|
+
constructor(message = 'Session serialization failed', cause) { super('SESSION_SERIALIZATION', message, { cause }); }
|
|
45
|
+
}
|
|
46
|
+
/** Thrown when session configuration is invalid or incomplete. */
|
|
47
|
+
export class SessionConfigurationError extends SessionError {
|
|
48
|
+
constructor(message) { super('SESSION_CONFIGURATION', message); }
|
|
49
|
+
}
|
|
50
|
+
/** Thrown when token or other session input is malformed. */
|
|
51
|
+
export class SessionInputError extends SessionError {
|
|
52
|
+
constructor(message) { super('SESSION_INPUT', message); }
|
|
53
|
+
}
|
|
54
|
+
/** Thrown when a configured session limit prevents an operation. */
|
|
55
|
+
export class SessionLimitError extends SessionError {
|
|
56
|
+
constructor(message) { super('SESSION_LIMIT', message); }
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/session/errors.ts"],"names":[],"mappings":"AAMA,+FAA+F;AAC/F,MAAM,OAAO,YAAa,SAAQ,KAAK;IACT;IAA5B,YAA4B,IAAsB,EAAE,OAAe,EAAE,OAAsB;QACzF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAkB;QACvB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IACtD,CAAC;CACF;AACD,mEAAmE;AACnE,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAAE;AAC7H,gEAAgE;AAChE,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAAE;AACxH,yDAAyD;AACzD,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAAE;AACxH,2DAA2D;AAC3D,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAAE;AACxH,6DAA6D;AAC7D,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,gBAAgB,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;CAAE;AAC9H,mDAAmD;AACnD,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAAG,YAAY,OAAO,GAAG,yBAAyB,EAAE,KAAe,IAAI,KAAK,CAAC,kBAAkB,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAAE;AAC/K,qEAAqE;AACrE,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAAG,gBAAgB,KAAK,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;CAAE;AACnI,gFAAgF;AAChF,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAAG,YAAY,OAAe,EAAE,KAAe,IAAI,KAAK,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAAE;AACzJ,wEAAwE;AACxE,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IAAG,YAAY,OAAO,GAAG,8BAA8B,EAAE,KAAe,IAAI,KAAK,CAAC,uBAAuB,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAAE;AAC9L,kEAAkE;AAClE,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IAAG,YAAY,OAAe,IAAI,KAAK,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAAE;AACzI,6DAA6D;AAC7D,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IAAG,YAAY,OAAe,IAAI,KAAK,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAAE;AACzH,oEAAoE;AACpE,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IAAG,YAAY,OAAe,IAAI,KAAK,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAAE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RedisClientWrapper } from '../redis/wrapper.js';
|
|
2
|
+
import type { RedisConfig } from '../redis/types.js';
|
|
3
|
+
import { type SessionConfig } from './config.js';
|
|
4
|
+
import { SessionManager } from './manager.js';
|
|
5
|
+
import type { KeyManager, SessionMetrics } from './types.js';
|
|
6
|
+
/** Dependencies and configuration required to construct a session manager. */
|
|
7
|
+
export interface CreateSessionManagerOptions {
|
|
8
|
+
redis: RedisClientWrapper;
|
|
9
|
+
config: SessionConfig;
|
|
10
|
+
encryptionKeyManager?: KeyManager;
|
|
11
|
+
metrics?: SessionMetrics;
|
|
12
|
+
}
|
|
13
|
+
/** Creates the session subsystem on top of an already-created shared Redis client. */
|
|
14
|
+
export declare function createSessionManager(options: CreateSessionManagerOptions): SessionManager;
|
|
15
|
+
/** Creates a session manager and shared Redis wrapper from separate configuration objects. */
|
|
16
|
+
export declare function createSessionManagerFromRedis(redisConfig: RedisConfig, sessionConfig: unknown): {
|
|
17
|
+
manager: SessionManager;
|
|
18
|
+
redis: RedisClientWrapper;
|
|
19
|
+
config: SessionConfig;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/session/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAMrE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI7D,8EAA8E;AAC9E,MAAM,WAAW,2BAA2B;IAAG,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,oBAAoB,CAAC,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CAAE;AAE/J,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAQzF;AAED,8FAA8F;AAC9F,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAI7K"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createRedisConnection } from '../redis/client.js';
|
|
2
|
+
import { parseSessionConfig } from './config.js';
|
|
3
|
+
import { SessionKeyStrategy } from './keys.js';
|
|
4
|
+
import { SessionSerializer } from './serializer.js';
|
|
5
|
+
import { SessionScriptRegistry } from './scripts.js';
|
|
6
|
+
import { SessionRepository } from './repository.js';
|
|
7
|
+
import { SessionService } from './service.js';
|
|
8
|
+
import { SessionManager } from './manager.js';
|
|
9
|
+
import { SessionTokenManager } from './token.js';
|
|
10
|
+
import { SessionConfigurationError } from './errors.js';
|
|
11
|
+
import { RedisClientWrapper as Wrapper } from '../redis/wrapper.js';
|
|
12
|
+
/** Creates the session subsystem on top of an already-created shared Redis client. */
|
|
13
|
+
export function createSessionManager(options) {
|
|
14
|
+
if (!options.config.enabled)
|
|
15
|
+
throw new SessionConfigurationError('Sessions are disabled');
|
|
16
|
+
const keys = new SessionKeyStrategy(options.config.namespace);
|
|
17
|
+
if (options.config.encryption.enabled && !options.encryptionKeyManager)
|
|
18
|
+
throw new SessionConfigurationError('Encryption is enabled but no key manager was supplied');
|
|
19
|
+
const serializer = new SessionSerializer(options.config.encryption.enabled ? options.encryptionKeyManager : undefined);
|
|
20
|
+
const scripts = new SessionScriptRegistry(options.redis);
|
|
21
|
+
const repository = new SessionRepository({ redis: options.redis, keys, serializer, scripts, config: options.config });
|
|
22
|
+
return new SessionManager(new SessionService({ repository, tokens: new SessionTokenManager(options.config.tokenBytes), redis: options.redis, config: options.config, ...(options.metrics ? { metrics: options.metrics } : {}) }));
|
|
23
|
+
}
|
|
24
|
+
/** Creates a session manager and shared Redis wrapper from separate configuration objects. */
|
|
25
|
+
export function createSessionManagerFromRedis(redisConfig, sessionConfig) {
|
|
26
|
+
const config = parseSessionConfig(sessionConfig);
|
|
27
|
+
const redis = new Wrapper(createRedisConnection(redisConfig));
|
|
28
|
+
return { manager: createSessionManager({ redis, config }), redis, config };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/session/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAsB,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,kBAAkB,IAAI,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKpE,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAAC,OAAoC;IACvE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,yBAAyB,CAAC,uBAAuB,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9D,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB;QAAE,MAAM,IAAI,yBAAyB,CAAC,uDAAuD,CAAC,CAAC;IACrK,MAAM,UAAU,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvH,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtH,OAAO,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACpO,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,6BAA6B,CAAC,WAAwB,EAAE,aAAsB;IAC5F,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9D,OAAO,EAAE,OAAO,EAAE,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RedisClientWrapper } from '../redis/wrapper.js';
|
|
2
|
+
import type { SessionHealth } from './types.js';
|
|
3
|
+
/** Performs a lightweight Redis health check for session infrastructure. */
|
|
4
|
+
export declare class SessionHealthProvider {
|
|
5
|
+
private readonly redis;
|
|
6
|
+
private readonly degradedMs;
|
|
7
|
+
/** Creates a health provider. `degradedMs` is the latency threshold for degraded status. */
|
|
8
|
+
constructor(redis: RedisClientWrapper, degradedMs?: number);
|
|
9
|
+
/** Performs one cheap Redis PING and classifies latency or availability. */
|
|
10
|
+
check(): Promise<SessionHealth>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/session/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,4EAA4E;AAC5E,qBAAa,qBAAqB;IAEpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAsB,OAAO,CAAC,QAAQ,CAAC,UAAU;IADnF,4FAA4F;gBAC/D,KAAK,EAAE,kBAAkB,EAAmB,UAAU,SAAM;IACzF,4EAA4E;IACtE,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC;CAUtC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Performs a lightweight Redis health check for session infrastructure. */
|
|
2
|
+
export class SessionHealthProvider {
|
|
3
|
+
redis;
|
|
4
|
+
degradedMs;
|
|
5
|
+
/** Creates a health provider. `degradedMs` is the latency threshold for degraded status. */
|
|
6
|
+
constructor(redis, degradedMs = 100) {
|
|
7
|
+
this.redis = redis;
|
|
8
|
+
this.degradedMs = degradedMs;
|
|
9
|
+
}
|
|
10
|
+
/** Performs one cheap Redis PING and classifies latency or availability. */
|
|
11
|
+
async check() {
|
|
12
|
+
const started = performance.now();
|
|
13
|
+
try {
|
|
14
|
+
const response = await this.redis.ping();
|
|
15
|
+
const latencyMs = performance.now() - started;
|
|
16
|
+
return { status: latencyMs > this.degradedMs ? 'degraded' : 'healthy', latencyMs, errorRate: 0, redisStatus: response };
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return { status: 'unhealthy', latencyMs: performance.now() - started, errorRate: 1, redisStatus: 'unavailable' };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/session/health.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,OAAO,qBAAqB;IAEH;IAA4C;IADzE,4FAA4F;IAC5F,YAA6B,KAAyB,EAAmB,aAAa,GAAG;QAA5D,UAAK,GAAL,KAAK,CAAoB;QAAmB,eAAU,GAAV,UAAU,CAAM;IAAG,CAAC;IAC7F,4EAA4E;IAC5E,KAAK,CAAC,KAAK;QACT,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YAC9C,OAAO,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;QAC1H,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QACnH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Centralizes session Redis key construction and user hash-tagging. */
|
|
2
|
+
export declare class SessionKeyStrategy {
|
|
3
|
+
private readonly namespace;
|
|
4
|
+
/** Creates a key strategy for a single logical session namespace. */
|
|
5
|
+
constructor(namespace: string);
|
|
6
|
+
/** Returns the configured logical namespace. */
|
|
7
|
+
getNamespace(): string;
|
|
8
|
+
/** Returns a deterministic SHA-256 tag suitable for Redis Cluster hash-tagging. */
|
|
9
|
+
userTag(userId: string): string;
|
|
10
|
+
/** Builds an authoritative session key for a user and token hash. */
|
|
11
|
+
session(userId: string, tokenHash: string): string;
|
|
12
|
+
/** Builds the same session key when the precomputed user tag is already available. */
|
|
13
|
+
sessionByTag(userTag: string, tokenHash: string): string;
|
|
14
|
+
/** Builds the per-user sorted-set index key. */
|
|
15
|
+
userIndex(userId: string): string;
|
|
16
|
+
/** Builds the per-user security-version key. */
|
|
17
|
+
securityVersion(userId: string): string;
|
|
18
|
+
/** Builds the secondary token-hash locator key. */
|
|
19
|
+
tokenIndex(tokenHash: string): string;
|
|
20
|
+
/** Builds a user-scoped SHA-256 idempotency key without storing the raw idempotency value. */
|
|
21
|
+
idempotency(userId: string, key: string): string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,qBAAa,kBAAkB;IAEjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IADtC,qEAAqE;gBACxC,SAAS,EAAE,MAAM;IAC9C,gDAAgD;IAChD,YAAY,IAAI,MAAM;IACtB,mFAAmF;IACnF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAC/B,qEAAqE;IACrE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAClD,sFAAsF;IACtF,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IACxD,gDAAgD;IAChD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IACjC,gDAAgD;IAChD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IACvC,mDAAmD;IACnD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IACrC,8FAA8F;IAC9F,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;CACjD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { safeUserTag } from '../redis/cluster.js';
|
|
3
|
+
/** Centralizes session Redis key construction and user hash-tagging. */
|
|
4
|
+
export class SessionKeyStrategy {
|
|
5
|
+
namespace;
|
|
6
|
+
/** Creates a key strategy for a single logical session namespace. */
|
|
7
|
+
constructor(namespace) {
|
|
8
|
+
this.namespace = namespace;
|
|
9
|
+
}
|
|
10
|
+
/** Returns the configured logical namespace. */
|
|
11
|
+
getNamespace() { return this.namespace; }
|
|
12
|
+
/** Returns a deterministic SHA-256 tag suitable for Redis Cluster hash-tagging. */
|
|
13
|
+
userTag(userId) { return safeUserTag(userId); }
|
|
14
|
+
/** Builds an authoritative session key for a user and token hash. */
|
|
15
|
+
session(userId, tokenHash) { return `${this.namespace}:session:{${this.userTag(userId)}}:${tokenHash}`; }
|
|
16
|
+
/** Builds the same session key when the precomputed user tag is already available. */
|
|
17
|
+
sessionByTag(userTag, tokenHash) { return `${this.namespace}:session:{${userTag}}:${tokenHash}`; }
|
|
18
|
+
/** Builds the per-user sorted-set index key. */
|
|
19
|
+
userIndex(userId) { return `${this.namespace}:user-sessions:{${this.userTag(userId)}}`; }
|
|
20
|
+
/** Builds the per-user security-version key. */
|
|
21
|
+
securityVersion(userId) { return `${this.namespace}:security-version:{${this.userTag(userId)}}`; }
|
|
22
|
+
/** Builds the secondary token-hash locator key. */
|
|
23
|
+
tokenIndex(tokenHash) { return `${this.namespace}:token-index:${tokenHash}`; }
|
|
24
|
+
/** Builds a user-scoped SHA-256 idempotency key without storing the raw idempotency value. */
|
|
25
|
+
idempotency(userId, key) { const h = createHash('sha256').update(key).digest('hex'); return `${this.namespace}:idem:{${this.userTag(userId)}}:${h}`; }
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,wEAAwE;AACxE,MAAM,OAAO,kBAAkB;IAEA;IAD7B,qEAAqE;IACrE,YAA6B,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAClD,gDAAgD;IAChD,YAAY,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,mFAAmF;IACnF,OAAO,CAAC,MAAc,IAAY,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/D,qEAAqE;IACrE,OAAO,CAAC,MAAc,EAAE,SAAiB,IAAY,OAAO,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC;IACjI,sFAAsF;IACtF,YAAY,CAAC,OAAe,EAAE,SAAiB,IAAY,OAAO,GAAG,IAAI,CAAC,SAAS,aAAa,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC;IAC1H,gDAAgD;IAChD,SAAS,CAAC,MAAc,IAAY,OAAO,GAAG,IAAI,CAAC,SAAS,mBAAmB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACzG,gDAAgD;IAChD,eAAe,CAAC,MAAc,IAAY,OAAO,GAAG,IAAI,CAAC,SAAS,sBAAsB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAClH,mDAAmD;IACnD,UAAU,CAAC,SAAiB,IAAY,OAAO,GAAG,IAAI,CAAC,SAAS,gBAAgB,SAAS,EAAE,CAAC,CAAC,CAAC;IAC9F,8FAA8F;IAC9F,WAAW,CAAC,MAAc,EAAE,GAAW,IAAY,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/K"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SessionService } from './service.js';
|
|
2
|
+
import type { CreateSessionInput, CreatedSession, RotationResult, SessionPatch, SessionRecord, ValidationResult } from './types.js';
|
|
3
|
+
/** Stable, framework-independent facade for session lifecycle operations. */
|
|
4
|
+
export declare class SessionManager {
|
|
5
|
+
private readonly service;
|
|
6
|
+
/** Creates a manager backed by the supplied service. */
|
|
7
|
+
constructor(service: SessionService);
|
|
8
|
+
/** Creates a new opaque session and returns its raw token exactly once. */
|
|
9
|
+
create(input: CreateSessionInput): Promise<CreatedSession>;
|
|
10
|
+
/** Validates a raw session token and returns a discriminated authentication result. */
|
|
11
|
+
validate(token: string): Promise<ValidationResult>;
|
|
12
|
+
/** Gets an active authoritative session or throws a typed session error. */
|
|
13
|
+
get(token: string): Promise<SessionRecord>;
|
|
14
|
+
/** Applies configured rolling idle-expiration behavior to an active session. */
|
|
15
|
+
touch(token: string): Promise<void>;
|
|
16
|
+
/** Updates mutable session metadata with optional optimistic concurrency control. */
|
|
17
|
+
update(token: string, patch: SessionPatch, expectedVersion?: number): Promise<SessionRecord>;
|
|
18
|
+
/** Atomically consumes a predecessor and creates a successor token. */
|
|
19
|
+
rotate(token: string): Promise<RotationResult>;
|
|
20
|
+
/** Permanently removes the session's stored record and derived indexes. */
|
|
21
|
+
destroy(token: string): Promise<void>;
|
|
22
|
+
/** Marks a session unusable for authentication. */
|
|
23
|
+
revoke(token: string): Promise<void>;
|
|
24
|
+
/** Sets the user's security version used by session validation when enabled. */
|
|
25
|
+
setSecurityVersion(userId: string, version: number): Promise<void>;
|
|
26
|
+
/** Revokes a bounded number of sessions for a user and reports remaining indexed sessions. */
|
|
27
|
+
revokeAll(userId: string, limit?: number): Promise<{
|
|
28
|
+
affected: number;
|
|
29
|
+
remaining: number;
|
|
30
|
+
}>;
|
|
31
|
+
/** Lists a bounded page of sessions for a user. */
|
|
32
|
+
list(userId: string, offset?: number, limit?: number): Promise<SessionRecord[]>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpI,6EAA6E;AAC7E,qBAAa,cAAc;IAEb,OAAO,CAAC,QAAQ,CAAC,OAAO;IADpC,wDAAwD;gBAC3B,OAAO,EAAE,cAAc;IACpD,2EAA2E;IAC3E,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IAC1D,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAClD,4EAA4E;IAC5E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAC1C,gFAAgF;IAChF,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACnC,qFAAqF;IACrF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAC5F,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAC9C,2EAA2E;IAC3E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACrC,mDAAmD;IACnD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACpC,gFAAgF;IAChF,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAClE,8FAA8F;IAC9F,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F,mDAAmD;IACnD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAChF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Stable, framework-independent facade for session lifecycle operations. */
|
|
2
|
+
export class SessionManager {
|
|
3
|
+
service;
|
|
4
|
+
/** Creates a manager backed by the supplied service. */
|
|
5
|
+
constructor(service) {
|
|
6
|
+
this.service = service;
|
|
7
|
+
}
|
|
8
|
+
/** Creates a new opaque session and returns its raw token exactly once. */
|
|
9
|
+
create(input) { return this.service.create(input); }
|
|
10
|
+
/** Validates a raw session token and returns a discriminated authentication result. */
|
|
11
|
+
validate(token) { return this.service.validate(token); }
|
|
12
|
+
/** Gets an active authoritative session or throws a typed session error. */
|
|
13
|
+
get(token) { return this.service.get(token); }
|
|
14
|
+
/** Applies configured rolling idle-expiration behavior to an active session. */
|
|
15
|
+
touch(token) { return this.service.touch(token); }
|
|
16
|
+
/** Updates mutable session metadata with optional optimistic concurrency control. */
|
|
17
|
+
update(token, patch, expectedVersion) { return this.service.update(token, patch, expectedVersion); }
|
|
18
|
+
/** Atomically consumes a predecessor and creates a successor token. */
|
|
19
|
+
rotate(token) { return this.service.rotate(token); }
|
|
20
|
+
/** Permanently removes the session's stored record and derived indexes. */
|
|
21
|
+
destroy(token) { return this.service.destroy(token); }
|
|
22
|
+
/** Marks a session unusable for authentication. */
|
|
23
|
+
revoke(token) { return this.service.revoke(token); }
|
|
24
|
+
/** Sets the user's security version used by session validation when enabled. */
|
|
25
|
+
setSecurityVersion(userId, version) { return this.service.setSecurityVersion(userId, version); }
|
|
26
|
+
/** Revokes a bounded number of sessions for a user and reports remaining indexed sessions. */
|
|
27
|
+
revokeAll(userId, limit) { return this.service.revokeAll(userId, limit); }
|
|
28
|
+
/** Lists a bounded page of sessions for a user. */
|
|
29
|
+
list(userId, offset, limit) { return this.service.list(userId, offset, limit); }
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"AAGA,6EAA6E;AAC7E,MAAM,OAAO,cAAc;IAEI;IAD7B,wDAAwD;IACxD,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IACxD,2EAA2E;IAC3E,MAAM,CAAC,KAAyB,IAA6B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjG,uFAAuF;IACvF,QAAQ,CAAC,KAAa,IAA+B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3F,4EAA4E;IAC5E,GAAG,CAAC,KAAa,IAA4B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9E,gFAAgF;IAChF,KAAK,CAAC,KAAa,IAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzE,qFAAqF;IACrF,MAAM,CAAC,KAAa,EAAE,KAAmB,EAAE,eAAwB,IAA4B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3J,uEAAuE;IACvE,MAAM,CAAC,KAAa,IAA6B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrF,2EAA2E;IAC3E,OAAO,CAAC,KAAa,IAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7E,mDAAmD;IACnD,MAAM,CAAC,KAAa,IAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,gFAAgF;IAChF,kBAAkB,CAAC,MAAc,EAAE,OAAe,IAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/H,8FAA8F;IAC9F,SAAS,CAAC,MAAc,EAAE,KAAc,IAAsD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7I,mDAAmD;IACnD,IAAI,CAAC,MAAc,EAAE,MAAe,EAAE,KAAc,IAA8B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CACrI"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionMetrics } from './types.js';
|
|
2
|
+
/** No-op metrics sink for applications that do not configure instrumentation. */
|
|
3
|
+
export declare class NoopMetrics implements SessionMetrics {
|
|
4
|
+
/** Ignores counter increments. */
|
|
5
|
+
increment(): void;
|
|
6
|
+
/** Ignores observations. */
|
|
7
|
+
observe(): void;
|
|
8
|
+
/** Ignores gauge updates. */
|
|
9
|
+
gauge(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/session/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,iFAAiF;AACjF,qBAAa,WAAY,YAAW,cAAc;IAChD,kCAAkC;IAClC,SAAS,IAAI,IAAI;IACjB,4BAA4B;IAC5B,OAAO,IAAI,IAAI;IACf,6BAA6B;IAC7B,KAAK,IAAI,IAAI;CACd"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** No-op metrics sink for applications that do not configure instrumentation. */
|
|
2
|
+
export class NoopMetrics {
|
|
3
|
+
/** Ignores counter increments. */
|
|
4
|
+
increment() { }
|
|
5
|
+
/** Ignores observations. */
|
|
6
|
+
observe() { }
|
|
7
|
+
/** Ignores gauge updates. */
|
|
8
|
+
gauge() { }
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/session/metrics.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,MAAM,OAAO,WAAW;IACtB,kCAAkC;IAClC,SAAS,KAAU,CAAC;IACpB,4BAA4B;IAC5B,OAAO,KAAU,CAAC;IAClB,6BAA6B;IAC7B,KAAK,KAAU,CAAC;CACjB"}
|