@nestjs-redisx/testing 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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/index.d.ts +10 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +1750 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +1739 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/memory/api/redis-testing.module.d.ts +20 -0
  10. package/dist/memory/api/redis-testing.module.d.ts.map +1 -0
  11. package/dist/memory/api/register-memory-driver.d.ts +8 -0
  12. package/dist/memory/api/register-memory-driver.d.ts.map +1 -0
  13. package/dist/memory/application/ports/command-executor.port.d.ts +9 -0
  14. package/dist/memory/application/ports/command-executor.port.d.ts.map +1 -0
  15. package/dist/memory/application/services/command-executor.service.d.ts +49 -0
  16. package/dist/memory/application/services/command-executor.service.d.ts.map +1 -0
  17. package/dist/memory/domain/lua/lua-interpreter.d.ts +46 -0
  18. package/dist/memory/domain/lua/lua-interpreter.d.ts.map +1 -0
  19. package/dist/memory/domain/lua/lua-lexer.d.ts +11 -0
  20. package/dist/memory/domain/lua/lua-lexer.d.ts.map +1 -0
  21. package/dist/memory/domain/lua/lua-parser.d.ts +67 -0
  22. package/dist/memory/domain/lua/lua-parser.d.ts.map +1 -0
  23. package/dist/memory/domain/lua/redis-call.port.d.ts +7 -0
  24. package/dist/memory/domain/lua/redis-call.port.d.ts.map +1 -0
  25. package/dist/memory/domain/store/memory-store.d.ts +59 -0
  26. package/dist/memory/domain/store/memory-store.d.ts.map +1 -0
  27. package/dist/memory/domain/store/stream-value.d.ts +74 -0
  28. package/dist/memory/domain/store/stream-value.d.ts.map +1 -0
  29. package/dist/memory/infrastructure/adapters/memory-redis.adapter.d.ts +22 -0
  30. package/dist/memory/infrastructure/adapters/memory-redis.adapter.d.ts.map +1 -0
  31. package/dist/shared/constants/index.d.ts +6 -0
  32. package/dist/shared/constants/index.d.ts.map +1 -0
  33. package/dist/shared/errors/index.d.ts +22 -0
  34. package/dist/shared/errors/index.d.ts.map +1 -0
  35. package/dist/shared/types/index.d.ts +19 -0
  36. package/dist/shared/types/index.d.ts.map +1 -0
  37. package/package.json +76 -0
@@ -0,0 +1,67 @@
1
+ export type Expr = {
2
+ kind: 'num';
3
+ value: number;
4
+ } | {
5
+ kind: 'str';
6
+ value: string;
7
+ } | {
8
+ kind: 'bool';
9
+ value: boolean;
10
+ } | {
11
+ kind: 'nil';
12
+ } | {
13
+ kind: 'name';
14
+ name: string;
15
+ } | {
16
+ kind: 'index';
17
+ obj: Expr;
18
+ key: Expr;
19
+ } | {
20
+ kind: 'call';
21
+ callee: Expr;
22
+ args: Expr[];
23
+ } | {
24
+ kind: 'table';
25
+ items: Expr[];
26
+ } | {
27
+ kind: 'unop';
28
+ op: string;
29
+ expr: Expr;
30
+ } | {
31
+ kind: 'binop';
32
+ op: string;
33
+ left: Expr;
34
+ right: Expr;
35
+ };
36
+ export type Stmt = {
37
+ kind: 'local';
38
+ name: string;
39
+ expr?: Expr;
40
+ } | {
41
+ kind: 'assign';
42
+ target: Expr;
43
+ expr: Expr;
44
+ } | {
45
+ kind: 'if';
46
+ clauses: Array<{
47
+ cond: Expr;
48
+ body: Stmt[];
49
+ }>;
50
+ elseBody?: Stmt[];
51
+ } | {
52
+ kind: 'for';
53
+ varName: string;
54
+ from: Expr;
55
+ to: Expr;
56
+ step?: Expr;
57
+ body: Stmt[];
58
+ } | {
59
+ kind: 'return';
60
+ expr?: Expr;
61
+ } | {
62
+ kind: 'exprStmt';
63
+ expr: Expr;
64
+ };
65
+ /** Parses the supported Lua subset into a statement list. */
66
+ export declare function parse(src: string): Stmt[];
67
+ //# sourceMappingURL=lua-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lua-parser.d.ts","sourceRoot":"","sources":["../../../../src/memory/domain/lua/lua-parser.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzY,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,IAAI,EAAE,CAAA;KAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAuB1V,6DAA6D;AAC7D,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,CA4NzC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Bridge handed to the Lua interpreter so `redis.call(cmd, ...args)` inside a
3
+ * script can execute against the same in-memory store. Implemented by the
4
+ * application CommandExecutor; the interpreter (domain) only depends on this port.
5
+ */
6
+ export type RedisCallPort = (command: string, args: Array<string | number>) => unknown;
7
+ //# sourceMappingURL=redis-call.port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-call.port.d.ts","sourceRoot":"","sources":["../../../../src/memory/domain/lua/redis-call.port.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { StreamValue } from './stream-value';
2
+ /**
3
+ * Tagged union of the Redis value types the in-memory store supports:
4
+ * string, hash, set, sorted set, list (Phase 1) and stream (Phase 2).
5
+ */
6
+ export type StoredValue = {
7
+ kind: 'string';
8
+ value: string;
9
+ } | {
10
+ kind: 'hash';
11
+ value: Map<string, string>;
12
+ } | {
13
+ kind: 'set';
14
+ value: Set<string>;
15
+ } | {
16
+ kind: 'zset';
17
+ value: Map<string, number>;
18
+ } | {
19
+ kind: 'list';
20
+ value: string[];
21
+ } | {
22
+ kind: 'stream';
23
+ value: StreamValue;
24
+ };
25
+ export type RedisValueKind = StoredValue['kind'];
26
+ /** The concrete value type backing a given Redis kind. */
27
+ export type ValueOfKind<K extends RedisValueKind> = K extends 'string' ? string : K extends 'hash' ? Map<string, string> : K extends 'set' ? Set<string> : K extends 'zset' ? Map<string, number> : K extends 'list' ? string[] : K extends 'stream' ? StreamValue : never;
28
+ /**
29
+ * A single in-memory Redis keyspace with lazy TTL expiry.
30
+ *
31
+ * Pure data structure (no NestJS, no I/O). All command behavior lives in the
32
+ * application CommandExecutor; the store only stores and type-checks.
33
+ */
34
+ export declare class MemoryStore {
35
+ private readonly keyspace;
36
+ /** Current logical time (epoch ms). Overridable for deterministic TTL tests. */
37
+ now(): number;
38
+ /** Returns the live entry for a key, lazily evicting it if expired. */
39
+ private live;
40
+ has(key: string): boolean;
41
+ /** Deletes a key. Returns true if a live key was removed. */
42
+ delete(key: string): boolean;
43
+ /** Returns the Redis type name, or 'none' if missing. */
44
+ type(key: string): string;
45
+ flush(): void;
46
+ keys(): string[];
47
+ /** Sets absolute expiry (epoch ms) or null to persist. Returns true if key exists. */
48
+ setExpireAt(key: string, atMs: number | null): boolean;
49
+ /** Remaining TTL in ms: -2 missing, -1 no expiry, else >= 0. */
50
+ pttl(key: string): number;
51
+ /** Reads a container of the expected kind; undefined if missing; throws on type mismatch. */
52
+ read<K extends RedisValueKind>(key: string, kind: K): ValueOfKind<K> | undefined;
53
+ /** Gets the existing container of `kind`, creating an empty one (no expiry) if absent. Throws on type mismatch. */
54
+ readOrCreate<K extends RedisValueKind>(key: string, kind: K): ValueOfKind<K>;
55
+ /** Overwrites a key with a string value, clearing any previous type and expiry. */
56
+ writeString(key: string, value: string): void;
57
+ private emptyContainer;
58
+ }
59
+ //# sourceMappingURL=memory-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../../../src/memory/domain/store/memory-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAE7Q,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAEjD,0DAA0D;AAC1D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,IAAI,CAAC,SAAS,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,SAAS,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC;AAQ3Q;;;;;GAKG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAErD,gFAAgF;IAChF,GAAG,IAAI,MAAM;IAIb,uEAAuE;IACvE,OAAO,CAAC,IAAI;IAUZ,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,6DAA6D;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM5B,yDAAyD;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIzB,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,MAAM,EAAE;IAUhB,sFAAsF;IACtF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAOtD,gEAAgE;IAChE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IASzB,6FAA6F;IAC7F,IAAI,CAAC,CAAC,SAAS,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAOhF,mHAAmH;IACnH,YAAY,CAAC,CAAC,SAAS,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IAQ5E,mFAAmF;IACnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7C,OAAO,CAAC,cAAc;CAgBvB"}
@@ -0,0 +1,74 @@
1
+ /** A single stream entry: an id and a flat [field, value, ...] array. */
2
+ export type StreamEntry = {
3
+ id: string;
4
+ fields: string[];
5
+ };
6
+ /** A pending (delivered, not-yet-acked) entry in a group's PEL. */
7
+ export type PendingEntry = {
8
+ consumer: string;
9
+ /** Last delivery time (epoch ms) — used to compute idle time. */
10
+ deliveryTime: number;
11
+ deliveryCount: number;
12
+ };
13
+ /** A consumer group: its delivery cursor and pending-entries list (PEL). */
14
+ export type StreamGroup = {
15
+ lastDeliveredId: string;
16
+ pending: Map<string, PendingEntry>;
17
+ consumers: Set<string>;
18
+ };
19
+ /** Compares two `<ms>-<seq>` ids. Returns <0, 0, or >0. */
20
+ export declare function compareIds(a: string, b: string): number;
21
+ /**
22
+ * In-memory Redis Stream: an ordered entry log plus consumer groups with
23
+ * per-group delivery cursors and pending-entries lists (PEL). Pure data
24
+ * structure — the caller passes the current time so it stays deterministic.
25
+ */
26
+ export declare class StreamValue {
27
+ readonly entries: StreamEntry[];
28
+ lastId: string;
29
+ readonly groups: Map<string, StreamGroup>;
30
+ /** Computes the next auto id (`*`) given the current time, keeping ids monotonic. */
31
+ private nextAutoId;
32
+ /** Resolves an explicit or `*` id for XADD, validating monotonicity. */
33
+ private resolveAddId;
34
+ /** Appends an entry. Returns its id. */
35
+ add(id: string, fields: string[], now: number): string;
36
+ len(): number;
37
+ /** Entries within [start, end] (inclusive bounds, `-`/`+`/`(` supported). */
38
+ range(start: string, end: string, count?: number, reverse?: boolean): StreamEntry[];
39
+ /** Deletes entries by id. Returns the number removed. */
40
+ del(ids: string[]): number;
41
+ /** Trims to at most `maxLen` newest entries. Returns the number removed. */
42
+ trimMaxLen(maxLen: number): number;
43
+ createGroup(name: string, startId: string): void;
44
+ destroyGroup(name: string): number;
45
+ setGroupId(name: string, id: string): void;
46
+ delConsumer(name: string, consumer: string): number;
47
+ private requireGroup;
48
+ /**
49
+ * XREADGROUP semantics. `id === '>'` delivers never-delivered entries and adds
50
+ * them to the consumer's PEL; an explicit id re-reads that consumer's pending
51
+ * history with id greater than the given one.
52
+ */
53
+ readGroup(name: string, consumer: string, id: string, now: number, count: number | undefined, noAck: boolean): StreamEntry[];
54
+ ack(name: string, ids: string[]): number;
55
+ /** XPENDING summary: total, min/max pending id, and per-consumer counts. */
56
+ pendingSummary(name: string): {
57
+ count: number;
58
+ minId: string | null;
59
+ maxId: string | null;
60
+ consumers: Array<[string, number]>;
61
+ };
62
+ /** XPENDING range: pending entries in [start,end], optionally filtered by consumer. */
63
+ pendingRange(name: string, start: string, end: string, count: number, now: number, consumer?: string): Array<{
64
+ id: string;
65
+ consumer: string;
66
+ idleTime: number;
67
+ deliveryCount: number;
68
+ }>;
69
+ /** XCLAIM: reassign pending entries idle >= minIdle to `consumer`. Returns claimed entries. */
70
+ claim(name: string, consumer: string, minIdle: number, ids: string[], now: number): StreamEntry[];
71
+ /** Entries strictly greater than `id` (XREAD); `$` resolves to the current last id. */
72
+ readAfter(id: string, count?: number): StreamEntry[];
73
+ }
74
+ //# sourceMappingURL=stream-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-value.d.ts","sourceRoot":"","sources":["../../../../src/memory/domain/store/stream-value.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { BaseRedisDriver, type ConnectionConfig, type IPipeline, type IMulti } from '@nestjs-redisx/core';
2
+ import { MemoryStore } from '../../domain/store/memory-store';
3
+ /**
4
+ * In-memory `IRedisDriver` for tests. Implements the 5 `BaseRedisDriver`
5
+ * abstract methods over an in-memory store + Lua interpreter; the other ~186
6
+ * driver methods are inherited.
7
+ */
8
+ export declare class MemoryRedisAdapter extends BaseRedisDriver {
9
+ private readonly store;
10
+ private readonly executor;
11
+ constructor(config: ConnectionConfig, options?: {
12
+ enableLogging?: boolean;
13
+ });
14
+ /** Exposes the backing store for assertions / manual reset in tests. */
15
+ getStore(): MemoryStore;
16
+ protected doConnect(): Promise<void>;
17
+ protected doDisconnect(): Promise<void>;
18
+ protected executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
19
+ protected createPipeline(): IPipeline;
20
+ protected createMulti(): IMulti;
21
+ }
22
+ //# sourceMappingURL=memory-redis.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-redis.adapter.d.ts","sourceRoot":"","sources":["../../../../src/memory/infrastructure/adapters/memory-redis.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAE5H,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAqG9D;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,eAAe;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAE/B,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE;IAM3E,wEAAwE;IACxE,QAAQ,IAAI,WAAW;IAIvB,SAAS,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpC,SAAS,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cAKvB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBrF,SAAS,CAAC,cAAc,IAAI,SAAS;IAIrC,SAAS,CAAC,WAAW,IAAI,MAAM;CAGhC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Driver type identifier registered with the core driver registry.
3
+ * Use it via `RedisModule.forRoot({ clients: { type: MEMORY_DRIVER_TYPE } })`.
4
+ */
5
+ export declare const MEMORY_DRIVER_TYPE = "memory";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/constants/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { RedisXError } from '@nestjs-redisx/core';
2
+ /**
3
+ * Base error for the in-memory testing driver.
4
+ */
5
+ export declare class MemoryDriverError extends RedisXError {
6
+ constructor(message: string, cause?: Error);
7
+ }
8
+ /**
9
+ * Thrown when a Lua script uses a construct or command the in-memory
10
+ * interpreter does not support. Failing loudly prevents silent wrong results.
11
+ */
12
+ export declare class LuaExecutionError extends MemoryDriverError {
13
+ constructor(message: string, cause?: Error);
14
+ }
15
+ /**
16
+ * Thrown when a command targets a key holding the wrong data type
17
+ * (mirrors Redis WRONGTYPE).
18
+ */
19
+ export declare class WrongTypeError extends MemoryDriverError {
20
+ constructor();
21
+ }
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAa,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,iBAAiB;gBAC1C,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,iBAAiB;;CAKpD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Options for the in-memory Redis driver.
3
+ *
4
+ * @public
5
+ */
6
+ export interface IMemoryDriverOptions {
7
+ /**
8
+ * Seed initial string keys before the test runs.
9
+ *
10
+ * @example { 'user:1': '{"id":1}' }
11
+ */
12
+ seed?: Record<string, string>;
13
+ /**
14
+ * Enable operation logging (inherited driver behavior).
15
+ * @default false
16
+ */
17
+ enableLogging?: boolean;
18
+ }
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@nestjs-redisx/testing",
3
+ "version": "1.5.0",
4
+ "description": "Testing utilities for NestJS RedisX: an in-memory Redis driver for unit-testing without a running Redis",
5
+ "author": "NestJS RedisX Team",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "require": "./dist/index.js",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "test": "SKIP_INTEGRATION=true vitest run",
25
+ "test:watch": "SKIP_INTEGRATION=true vitest",
26
+ "test:cov": "SKIP_INTEGRATION=true vitest run --coverage",
27
+ "test:integration": "vitest run test/integration",
28
+ "lint": "eslint \"{src,test}/**/*.ts\"",
29
+ "format": "prettier --write \"{src,test}/**/*.ts\""
30
+ },
31
+ "keywords": [
32
+ "nestjs",
33
+ "redis",
34
+ "testing",
35
+ "in-memory",
36
+ "mock",
37
+ "fake",
38
+ "test-driver"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/nestjs-redisx/nestjs-redisx.git",
43
+ "directory": "packages/testing"
44
+ },
45
+ "homepage": "https://nestjs-redisx.dev/en/reference/testing/",
46
+ "bugs": {
47
+ "url": "https://github.com/nestjs-redisx/nestjs-redisx/issues"
48
+ },
49
+ "peerDependencies": {
50
+ "@nestjs-redisx/core": "^1.0.0",
51
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
52
+ "@nestjs/core": "^10.0.0 || ^11.0.0",
53
+ "reflect-metadata": "^0.2.0",
54
+ "rxjs": "^7.8.0"
55
+ },
56
+ "devDependencies": {
57
+ "@nestjs-redisx/cache": "^1.5.0",
58
+ "@nestjs-redisx/idempotency": "^1.5.0",
59
+ "@nestjs-redisx/locks": "^1.5.0",
60
+ "@nestjs-redisx/rate-limit": "^1.5.0",
61
+ "@nestjs-redisx/streams": "^1.5.0",
62
+ "@nestjs/testing": "^9.0.0 || ^10.0.0 || ^11.0.0",
63
+ "@types/node": "^20.0.0",
64
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
65
+ "@typescript-eslint/parser": "^6.0.0",
66
+ "eslint": "^8.0.0",
67
+ "prettier": "^3.0.0",
68
+ "tsup": "^8.0.0",
69
+ "typescript": "^5.3.0",
70
+ "vitest": "^1.6.0",
71
+ "@vitest/coverage-v8": "^1.6.0"
72
+ },
73
+ "publishConfig": {
74
+ "access": "public"
75
+ }
76
+ }