@alpha018/nestjs-redisom 1.0.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 (38) hide show
  1. package/CONTRIBUTING.md +34 -0
  2. package/LICENSE +21 -0
  3. package/README.md +216 -0
  4. package/dist/index.d.ts +7 -0
  5. package/dist/index.js +24 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/redis-om/common/base.entity.d.ts +7 -0
  8. package/dist/redis-om/common/base.entity.js +13 -0
  9. package/dist/redis-om/common/base.entity.js.map +1 -0
  10. package/dist/redis-om/common/redis-om.utils.d.ts +3 -0
  11. package/dist/redis-om/common/redis-om.utils.js +17 -0
  12. package/dist/redis-om/common/redis-om.utils.js.map +1 -0
  13. package/dist/redis-om/decorators/inject-repository.decorator.d.ts +2 -0
  14. package/dist/redis-om/decorators/inject-repository.decorator.js +10 -0
  15. package/dist/redis-om/decorators/inject-repository.decorator.js.map +1 -0
  16. package/dist/redis-om/decorators/prop.decorator.d.ts +22 -0
  17. package/dist/redis-om/decorators/prop.decorator.js +12 -0
  18. package/dist/redis-om/decorators/prop.decorator.js.map +1 -0
  19. package/dist/redis-om/decorators/schema.decorator.d.ts +6 -0
  20. package/dist/redis-om/decorators/schema.decorator.js +10 -0
  21. package/dist/redis-om/decorators/schema.decorator.js.map +1 -0
  22. package/dist/redis-om/factories/schema.factory.d.ts +10 -0
  23. package/dist/redis-om/factories/schema.factory.js +60 -0
  24. package/dist/redis-om/factories/schema.factory.js.map +1 -0
  25. package/dist/redis-om/interfaces/index.d.ts +16 -0
  26. package/dist/redis-om/interfaces/index.js +3 -0
  27. package/dist/redis-om/interfaces/index.js.map +1 -0
  28. package/dist/redis-om/redis-om-core.module.d.ts +8 -0
  29. package/dist/redis-om/redis-om-core.module.js +72 -0
  30. package/dist/redis-om/redis-om-core.module.js.map +1 -0
  31. package/dist/redis-om/redis-om.constants.d.ts +3 -0
  32. package/dist/redis-om/redis-om.constants.js +7 -0
  33. package/dist/redis-om/redis-om.constants.js.map +1 -0
  34. package/dist/redis-om/redis-om.module.d.ts +8 -0
  35. package/dist/redis-om/redis-om.module.js +54 -0
  36. package/dist/redis-om/redis-om.module.js.map +1 -0
  37. package/dist/tsconfig.build.tsbuildinfo +1 -0
  38. package/package.json +124 -0
@@ -0,0 +1,34 @@
1
+ # Contributing to nestjs-redisom
2
+
3
+ Thank you for your interest in contributing to nestjs-redisom! We appreciate your contributions and want to make the process as smooth as possible. Please follow these guidelines to ensure your contributions are integrated seamlessly into the project.
4
+
5
+ ## How to Contribute
6
+
7
+ 1. **Open an Issue:** Before starting work on a new feature or bug fix, we recommend opening an issue to discuss your ideas with the development team. This will help us ensure that your changes align with the project's vision and avoid duplicated efforts.
8
+
9
+ 2. **Fork the Repository:** Fork the main repository to your GitHub account. This will allow you to work on your changes independently.
10
+
11
+ 3. **Create a Branch:** Create a new branch in your fork for your changes. Use a descriptive name for the branch that reflects the changes you are making (e.g., `feature/new-feature` or `fix/bug-fix`).
12
+
13
+ 4. **Make Your Changes:** Make your changes in the new branch. Be sure to follow the project's coding conventions and write unit tests for your changes.
14
+
15
+ 5. **Submit a Pull Request:** Once you have finished your changes, submit a pull request from your branch to the main repository. Include a clear description of your changes and any relevant information.
16
+
17
+ 6. **Review and Merge:** The development team will review your pull request and provide feedback. Once your changes have been approved, they will be merged into the main repository.
18
+
19
+ ## Contribution Guidelines
20
+
21
+ - **Unit Tests:** Write unit tests for all your changes. This will help us ensure code quality and prevent regressions in the future.
22
+ - **Documentation:** Make sure to document your changes appropriately. Update existing documentation or create new documentation if necessary.
23
+ - **Coding Conventions:** Follow the project's coding conventions. Use a linter to ensure your code adheres to the established rules.
24
+ - **Commit Messages:** Write clear and descriptive commit messages that explain the changes you have made, remember you need follow the commit lint rules.
25
+
26
+ ## License
27
+
28
+ By contributing to this project, you agree that your contributions will be licensed under the same license as the project, which is the MIT License.
29
+
30
+ ## Contact
31
+
32
+ If you have any questions or need help, please feel free to contact us by opening an issue on GitHub.
33
+
34
+ Thank you again for your interest in contributing to nestjs-redisom! We look forward to seeing your contributions soon.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Tomás Alegre Sepúlveda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # NestJS RedisOM
2
+
3
+ <div align="center">
4
+ <a href="http://nestjs.com/" target="_blank">
5
+ <img src="https://nestjs.com/img/logo_text.svg" width="150" alt="Nest Logo" />
6
+ </a>
7
+ </div>
8
+
9
+ <h3 align="center">A NestJS module for RedisOM, providing a structured way to use Redis Stack JSON/Search features.</h3>
10
+
11
+ <div align="center">
12
+ <a href="https://nestjs.com" target="_blank">
13
+ <img src="https://img.shields.io/badge/built%20with-NestJs-red.svg" alt="Built with NestJS">
14
+ </a>
15
+ </div>
16
+
17
+
18
+ ## Description
19
+
20
+ This library seamlessly integrates [RedisOM](https://redis.io/docs/latest/integrate/redisom-for-node-js/) into NestJS, offering:
21
+ - **Decorator-based Schema Definition**: Define your entities using `@Schema` and `@Prop`.
22
+ - **Repository Injection**: Inject repositories directly into your services using `@InjectRepository`.
23
+ - **Seamless Connection**: Configure your Redis connection globally with `forRoot` or `forRootAsync`.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ $ npm install nestjs-redisom redis-om redis
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### 1. Define an Entity
34
+
35
+ Use the `@Schema()` decorator to define your entity and `@Prop()` for properties. Extends `BaseEntity` to easily access the auto-generated ID.
36
+
37
+ ```typescript
38
+ import { Schema } from 'nestjs-redisom';
39
+ import { Prop } from 'nestjs-redisom';
40
+ import { BaseEntity } from 'nestjs-redisom';
41
+
42
+ @Schema()
43
+ export class CatEntity extends BaseEntity {
44
+ @Prop()
45
+ name: string;
46
+
47
+ @Prop()
48
+ age: number;
49
+ }
50
+ ```
51
+
52
+ ### 2. Import the Module
53
+
54
+ Register `RedisOmModule` in your root `AppModule` and register your entities with `forFeature`.
55
+
56
+ ```typescript
57
+ import { Module } from '@nestjs/common';
58
+ import { RedisOmModule } from 'nestjs-redisom';
59
+ import { CatEntity } from './cat.entity';
60
+
61
+ @Module({
62
+ imports: [
63
+ RedisOmModule.forRoot({
64
+ url: 'redis://localhost:6379'
65
+ }),
66
+ RedisOmModule.forFeature([CatEntity]),
67
+ ],
68
+ })
69
+ export class AppModule {}
70
+ ```
71
+
72
+ ### 3. Usage in a Service
73
+
74
+ Inject the repository to save and search for entities.
75
+
76
+ ```typescript
77
+ import { Injectable } from '@nestjs/common';
78
+ import { InjectRepository } from 'nestjs-redisom';
79
+ import { Repository } from 'redis-om';
80
+ import { CatEntity } from './cat.entity';
81
+
82
+ @Injectable()
83
+ export class CatsService {
84
+ constructor(
85
+ @InjectRepository(CatEntity) private readonly catRepo: Repository<CatEntity>,
86
+ ) {}
87
+
88
+ async create(name: string, age: number) {
89
+ const entity = new CatEntity();
90
+ entity.name = name;
91
+ entity.age = age;
92
+ return await this.catRepo.save(entity);
93
+ }
94
+
95
+ async findAll() {
96
+ return await this.catRepo.search().return.all();
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Advanced Usage
102
+
103
+ ### 1. Nested Typed Objects
104
+
105
+ You can define nested objects using classes and the `@Prop({ type: () => Class })` syntax. This allows Redis OM to automatically generate the correct schema fields (flattened) for your nested data.
106
+
107
+ **Define the Embedded Class:**
108
+
109
+ ```typescript
110
+ export class Address {
111
+ @Prop({ indexed: true })
112
+ city: string;
113
+
114
+ @Prop()
115
+ zip: string;
116
+ }
117
+ ```
118
+
119
+ **Use in Parent Entity:**
120
+
121
+ ```typescript
122
+ @Schema({ dataStructure: 'JSON' })
123
+ export class Person extends BaseEntity {
124
+ @Prop()
125
+ name: string;
126
+
127
+ @Prop({ type: () => Address })
128
+ address: Address;
129
+ }
130
+ ```
131
+
132
+ **Search using flattened/nested fields:**
133
+
134
+ The schema generator creates flattened fields like `address_city`.
135
+
136
+ ```typescript
137
+ // Search for persons living in 'New York'
138
+ const results = await this.personRepo.search()
139
+ .where('address_city' as any).eq('New York')
140
+ .return.all();
141
+ ```
142
+
143
+ ### 2. Custom IDs
144
+
145
+ You can explicitly set the ID when saving an entity if you don't want to use the auto-generated ULID. This is useful for using existing IDs (like UUIDs, emails, or external system IDs).
146
+
147
+ ```typescript
148
+ // Using a UUID
149
+ import { v4 as uuidv4 } from 'uuid';
150
+ const id = uuidv4();
151
+ await this.catRepo.save(id, entity);
152
+
153
+ // Using a custom string
154
+ await this.catRepo.save('unique-custom-id', entity);
155
+ ```
156
+
157
+ ### 3. TTL (Time To Live)
158
+
159
+ You can set an expiration time (in seconds) for an entity. The key will automatically be deleted from Redis after the specified time.
160
+
161
+ ```typescript
162
+ const id = 'temp-session-123';
163
+ await this.catRepo.save(id, sessionEntity);
164
+
165
+ // Expire after 60 seconds
166
+ await this.catRepo.expire(id, 60);
167
+ ```
168
+
169
+ ## Features
170
+
171
+ - **Schema Factory**: Automatically generates RedisOM schemas from your class metadata.
172
+ - **Nested Objects**: Support for typed nested objects with automatic schema flattening.
173
+ - **Async Configuration**: Supports `useFactory`, `useClass`, and `useExisting` for configuration.
174
+ - **Validation**: Compatible with `class-validator` (standard NestJS practice).
175
+
176
+ ## Performance & Search Mechanics
177
+
178
+ This library leverages **RediSearch** (module of Redis Stack), meaning searches are **efficient and non-blocking**.
179
+
180
+ ### 1. How Search Works
181
+ When you use `@Prop({ indexed: true })`, Redis OM creates an **Inverted Index**.
182
+ - **Search**: `repo.search()...` queries this index directly. It does **NOT** perform a linear scan (SCAN command) over the keyspace.
183
+ - **Complexity**: Searches are typically **O(K)** (where K is the number of results) or **O(log N)** for range queries. Retrieving by ID is **O(1)**.
184
+
185
+ #### Search Complexity by Type
186
+
187
+ | Data Type | Operation | Complexity | Notes |
188
+ | :--- | :--- | :--- | :--- |
189
+ | **ID** | Retrieve (`fetch`) | **O(1)** | Direct key access (fastest). |
190
+ | **Tag / String** | Exact Match (`eq`) | **O(K)** | `K` = number of results returned. |
191
+ | **Numeric / Date** | Range (`gt`, `lt`, `between`) | **O(log N + K)** | Uses sorted sets/trees. efficient for ranges. |
192
+ | **Text** | Full-Text (`matches`) | **O(M + K)** | `M` = number of terms/words being searched. |
193
+ | **Geo** | Radius / Polygon | **O(K + log N)** | Geospacial indexing. |
194
+
195
+ ### 2. Resource Usage
196
+ - **Memory (RAM)**: Indexes consume additional memory. **Best Practice:** Only index fields that you intend to filter by.
197
+ - **CPU**: Search operations are highly optimized. Initial indexing of a large existing dataset may temporarily consume CPU, but incremental updates (`save`) are lightweight.
198
+
199
+ ## Resources
200
+
201
+ Check out a few resources that may come in handy when working with NestJS:
202
+
203
+ - Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
204
+ - Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
205
+
206
+ ## Support
207
+
208
+ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
209
+
210
+ ## Stay in touch
211
+
212
+ - Author - [Tomás Alegre](https://github.com/Alpha018)
213
+
214
+ ## License
215
+
216
+ NestJS RedisOM is [MIT licensed](LICENSE).
@@ -0,0 +1,7 @@
1
+ export * from './redis-om/decorators/inject-repository.decorator';
2
+ export * from './redis-om/decorators/schema.decorator';
3
+ export * from './redis-om/decorators/prop.decorator';
4
+ export * from './redis-om/redis-om-core.module';
5
+ export * from './redis-om/common/base.entity';
6
+ export * from './redis-om/redis-om.module';
7
+ export * from './redis-om/interfaces';
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./redis-om/decorators/inject-repository.decorator"), exports);
18
+ __exportStar(require("./redis-om/decorators/schema.decorator"), exports);
19
+ __exportStar(require("./redis-om/decorators/prop.decorator"), exports);
20
+ __exportStar(require("./redis-om/redis-om-core.module"), exports);
21
+ __exportStar(require("./redis-om/common/base.entity"), exports);
22
+ __exportStar(require("./redis-om/redis-om.module"), exports);
23
+ __exportStar(require("./redis-om/interfaces"), exports);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oFAAkE;AAClE,yEAAuD;AACvD,uEAAqD;AACrD,kEAAgD;AAChD,gEAA8C;AAC9C,6DAA2C;AAC3C,wDAAsC"}
@@ -0,0 +1,7 @@
1
+ import { EntityId } from 'redis-om';
2
+ export interface EntityWithId {
3
+ [EntityId]?: string;
4
+ }
5
+ export declare class BaseEntity {
6
+ static getId(entity: EntityWithId | object): undefined | string;
7
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseEntity = void 0;
4
+ const redis_om_1 = require("redis-om");
5
+ class BaseEntity {
6
+ static getId(entity) {
7
+ if (!entity)
8
+ return undefined;
9
+ return entity[redis_om_1.EntityId];
10
+ }
11
+ }
12
+ exports.BaseEntity = BaseEntity;
13
+ //# sourceMappingURL=base.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.entity.js","sourceRoot":"","sources":["../../../src/redis-om/common/base.entity.ts"],"names":[],"mappings":";;;AAAA,uCAAoC;AAMpC,MAAa,UAAU;IACrB,MAAM,CAAC,KAAK,CAAC,MAA6B;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,OAAQ,MAAuB,CAAC,mBAAQ,CAAC,CAAC;IAC5C,CAAC;CACF;AALD,gCAKC"}
@@ -0,0 +1,3 @@
1
+ import { Type } from '@nestjs/common';
2
+ export declare function getRepositoryToken(entity: Type<any> | string): string;
3
+ export declare function getConnectionToken(name?: string): string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRepositoryToken = getRepositoryToken;
4
+ exports.getConnectionToken = getConnectionToken;
5
+ function getRepositoryToken(entity) {
6
+ if (entity === null || entity === undefined) {
7
+ throw new Error('Entity cannot be null or undefined');
8
+ }
9
+ const name = typeof entity === 'string' ? entity : entity.name;
10
+ return `${name}Repository`;
11
+ }
12
+ function getConnectionToken(name) {
13
+ return name && name !== 'default'
14
+ ? `REDIS_OM_CONNECTION_${name}`
15
+ : 'REDIS_OM_CONNECTION';
16
+ }
17
+ //# sourceMappingURL=redis-om.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-om.utils.js","sourceRoot":"","sources":["../../../src/redis-om/common/redis-om.utils.ts"],"names":[],"mappings":";;AAEA,gDAMC;AAED,gDAIC;AAZD,SAAgB,kBAAkB,CAAC,MAA0B;IAC3D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAC/D,OAAO,GAAG,IAAI,YAAY,CAAC;AAC7B,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAAa;IAC9C,OAAO,IAAI,IAAI,IAAI,KAAK,SAAS;QAC/B,CAAC,CAAC,uBAAuB,IAAI,EAAE;QAC/B,CAAC,CAAC,qBAAqB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Type } from '@nestjs/common';
2
+ export declare const InjectRepository: (entity: Type<any>) => PropertyDecorator & ParameterDecorator;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InjectRepository = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const redis_om_utils_1 = require("../common/redis-om.utils");
6
+ const InjectRepository = (entity) => {
7
+ return (0, common_1.Inject)((0, redis_om_utils_1.getRepositoryToken)(entity));
8
+ };
9
+ exports.InjectRepository = InjectRepository;
10
+ //# sourceMappingURL=inject-repository.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-repository.decorator.js","sourceRoot":"","sources":["../../../src/redis-om/decorators/inject-repository.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAGxC,6DAA8D;AAEvD,MAAM,gBAAgB,GAAG,CAAC,MAAiB,EAAE,EAAE;IACpD,OAAO,IAAA,eAAM,EAAC,IAAA,mCAAkB,EAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC;AAFW,QAAA,gBAAgB,oBAE3B"}
@@ -0,0 +1,22 @@
1
+ export interface PropOptions {
2
+ type?: RedisOmFieldType;
3
+ caseSensitive?: boolean;
4
+ textSearch?: boolean;
5
+ normalized?: boolean;
6
+ sortable?: boolean;
7
+ separator?: string;
8
+ stemming?: boolean;
9
+ indexed?: boolean;
10
+ matcher?: string;
11
+ weight?: number;
12
+ field?: string;
13
+ path?: string;
14
+ }
15
+ export type RedisOmFieldType = {
16
+ (): {
17
+ new (...args: any[]): any;
18
+ };
19
+ } | {
20
+ new (...args: any[]): any;
21
+ } | 'string[]' | 'number[]' | 'boolean' | 'string' | 'number' | 'point' | 'date' | 'text';
22
+ export declare function Prop(options?: PropOptions): PropertyDecorator;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Prop = Prop;
4
+ const redis_om_constants_1 = require("../redis-om.constants");
5
+ function Prop(options = {}) {
6
+ return (target, propertyKey) => {
7
+ const existingProps = Reflect.getMetadata(redis_om_constants_1.REDIS_OM_PROP_METADATA, target.constructor) || [];
8
+ existingProps.push({ propertyKey, options });
9
+ Reflect.defineMetadata(redis_om_constants_1.REDIS_OM_PROP_METADATA, existingProps, target.constructor);
10
+ };
11
+ }
12
+ //# sourceMappingURL=prop.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prop.decorator.js","sourceRoot":"","sources":["../../../src/redis-om/decorators/prop.decorator.ts"],"names":[],"mappings":";;AA6BA,oBAWC;AAxCD,8DAA+D;AA6B/D,SAAgB,IAAI,CAAC,UAAuB,EAAE;IAC5C,OAAO,CAAC,MAAc,EAAE,WAA4B,EAAE,EAAE;QACtD,MAAM,aAAa,GACjB,OAAO,CAAC,WAAW,CAAC,2CAAsB,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACxE,aAAa,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,cAAc,CACpB,2CAAsB,EACtB,aAAa,EACb,MAAM,CAAC,WAAW,CACnB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface SchemaOptions {
2
+ dataStructure?: 'JSON' | 'HASH';
3
+ indexName?: string;
4
+ name?: string;
5
+ }
6
+ export declare function Schema(options?: SchemaOptions): ClassDecorator;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Schema = Schema;
4
+ const redis_om_constants_1 = require("../redis-om.constants");
5
+ function Schema(options = {}) {
6
+ return (target) => {
7
+ Reflect.defineMetadata(redis_om_constants_1.REDIS_OM_SCHEMA_METADATA, options, target);
8
+ };
9
+ }
10
+ //# sourceMappingURL=schema.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.decorator.js","sourceRoot":"","sources":["../../../src/redis-om/decorators/schema.decorator.ts"],"names":[],"mappings":";;AAQA,wBAIC;AAZD,8DAAiE;AAQjE,SAAgB,MAAM,CAAC,UAAyB,EAAE;IAChD,OAAO,CAAC,MAAc,EAAE,EAAE;QACxB,OAAO,CAAC,cAAc,CAAC,6CAAwB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { Schema } from 'redis-om';
3
+ export declare class SchemaFactory {
4
+ static createForClass(target: Type<any>): Schema;
5
+ private static processStandardField;
6
+ private static processNestedClass;
7
+ private static processProperty;
8
+ private static buildSchemaProperties;
9
+ private static isNestedClass;
10
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaFactory = void 0;
4
+ const redis_om_1 = require("redis-om");
5
+ const redis_om_constants_1 = require("../redis-om.constants");
6
+ class SchemaFactory {
7
+ static createForClass(target) {
8
+ const schemaOptions = Reflect.getMetadata(redis_om_constants_1.REDIS_OM_SCHEMA_METADATA, target);
9
+ if (!schemaOptions) {
10
+ throw new Error(`Class ${target.name} is not decorated with @Schema decorator`);
11
+ }
12
+ const schemaDefinition = {};
13
+ this.buildSchemaProperties(target, schemaDefinition);
14
+ return new redis_om_1.Schema(schemaOptions.name || target.name, schemaDefinition, {
15
+ ...schemaOptions,
16
+ });
17
+ }
18
+ static processStandardField(propertyKey, options, schemaDefinition, pathPrefix, keyPrefix) {
19
+ const fieldDefinition = { type: options.type || 'string' };
20
+ if (options.indexed) {
21
+ fieldDefinition.sortable = options.sortable;
22
+ }
23
+ Object.assign(fieldDefinition, options);
24
+ if (!fieldDefinition.path && pathPrefix !== '$') {
25
+ fieldDefinition.path = `${pathPrefix}.${propertyKey}`;
26
+ }
27
+ const fieldKey = keyPrefix ? `${keyPrefix}_${propertyKey}` : propertyKey;
28
+ schemaDefinition[fieldKey] = fieldDefinition;
29
+ }
30
+ static processNestedClass(type, propertyKey, schemaDefinition, pathPrefix, keyPrefix) {
31
+ const nestedPathPrefix = `${pathPrefix}.${propertyKey}`;
32
+ const nestedKeyPrefix = keyPrefix
33
+ ? `${keyPrefix}_${propertyKey}`
34
+ : propertyKey;
35
+ const nestedTarget = type.prototype instanceof Object ? type : type();
36
+ this.buildSchemaProperties(nestedTarget, schemaDefinition, nestedPathPrefix, nestedKeyPrefix);
37
+ }
38
+ static processProperty(prop, schemaDefinition, pathPrefix, keyPrefix) {
39
+ const { propertyKey, options } = prop;
40
+ const type = options.type;
41
+ if (this.isNestedClass(type)) {
42
+ this.processNestedClass(type, propertyKey, schemaDefinition, pathPrefix, keyPrefix);
43
+ }
44
+ else {
45
+ this.processStandardField(propertyKey, options, schemaDefinition, pathPrefix, keyPrefix);
46
+ }
47
+ }
48
+ static buildSchemaProperties(target, schemaDefinition, pathPrefix = '$', keyPrefix = '') {
49
+ const propMetadata = Reflect.getMetadata(redis_om_constants_1.REDIS_OM_PROP_METADATA, target) || [];
50
+ propMetadata.forEach((prop) => {
51
+ this.processProperty(prop, schemaDefinition, pathPrefix, keyPrefix);
52
+ });
53
+ }
54
+ static isNestedClass(type) {
55
+ return (typeof type === 'function' &&
56
+ ![Boolean, String, Number, Date].includes(type));
57
+ }
58
+ }
59
+ exports.SchemaFactory = SchemaFactory;
60
+ //# sourceMappingURL=schema.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.factory.js","sourceRoot":"","sources":["../../../src/redis-om/factories/schema.factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ModuleMetadata, Type } from '@nestjs/common';
2
+ import { RedisClientOptions } from 'redis';
3
+ export interface RedisOmModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
4
+ useFactory?: (...args: any[]) => Promise<RedisOmModuleOptions> | RedisOmModuleOptions;
5
+ useExisting?: Type<RedisOmOptionsFactory>;
6
+ useClass?: Type<RedisOmOptionsFactory>;
7
+ inject?: any[];
8
+ }
9
+ export interface RedisOmModelDefinition {
10
+ name?: string;
11
+ schema: any;
12
+ }
13
+ export interface RedisOmOptionsFactory {
14
+ createRedisOmOptions(): Promise<RedisOmModuleOptions> | RedisOmModuleOptions;
15
+ }
16
+ export type RedisOmModuleOptions = RedisClientOptions;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/redis-om/interfaces/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { OnApplicationShutdown, DynamicModule } from '@nestjs/common';
2
+ import { RedisOmModuleAsyncOptions, RedisOmModuleOptions } from './interfaces';
3
+ export declare class RedisOmCoreModule implements OnApplicationShutdown {
4
+ static forRootAsync(options: RedisOmModuleAsyncOptions): DynamicModule;
5
+ static forRoot(options: RedisOmModuleOptions): DynamicModule;
6
+ private static createAsyncProviders;
7
+ onApplicationShutdown(): Promise<void>;
8
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var RedisOmCoreModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.RedisOmCoreModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const redis_1 = require("redis");
13
+ const redis_om_constants_1 = require("./redis-om.constants");
14
+ const redis_om_utils_1 = require("./common/redis-om.utils");
15
+ let RedisOmCoreModule = RedisOmCoreModule_1 = class RedisOmCoreModule {
16
+ static forRootAsync(options) {
17
+ const asyncProviders = this.createAsyncProviders(options);
18
+ return {
19
+ providers: [
20
+ ...asyncProviders,
21
+ {
22
+ useFactory: async (opt) => {
23
+ const redisInfo = opt.url ? { ...opt } : opt;
24
+ const redisClient = (0, redis_1.createClient)(redisInfo);
25
+ await redisClient.connect();
26
+ return redisClient;
27
+ },
28
+ inject: [redis_om_constants_1.REDIS_OM_MODULE_OPTIONS],
29
+ provide: (0, redis_om_utils_1.getConnectionToken)(),
30
+ },
31
+ ],
32
+ exports: [(0, redis_om_utils_1.getConnectionToken)()],
33
+ module: RedisOmCoreModule_1,
34
+ imports: options.imports,
35
+ };
36
+ }
37
+ static forRoot(options) {
38
+ const redisOmConnectionProvider = {
39
+ useFactory: async () => {
40
+ const redisInfo = options.url ? { ...options } : options;
41
+ const redisClient = (0, redis_1.createClient)(redisInfo);
42
+ await redisClient.connect();
43
+ return redisClient;
44
+ },
45
+ provide: (0, redis_om_utils_1.getConnectionToken)(),
46
+ };
47
+ return {
48
+ providers: [redisOmConnectionProvider],
49
+ exports: [redisOmConnectionProvider],
50
+ module: RedisOmCoreModule_1,
51
+ };
52
+ }
53
+ static createAsyncProviders(options) {
54
+ if (options.useFactory) {
55
+ return [
56
+ {
57
+ provide: redis_om_constants_1.REDIS_OM_MODULE_OPTIONS,
58
+ useFactory: options.useFactory,
59
+ inject: options.inject || [],
60
+ },
61
+ ];
62
+ }
63
+ return [];
64
+ }
65
+ async onApplicationShutdown() { }
66
+ };
67
+ exports.RedisOmCoreModule = RedisOmCoreModule;
68
+ exports.RedisOmCoreModule = RedisOmCoreModule = RedisOmCoreModule_1 = __decorate([
69
+ (0, common_1.Module)({}),
70
+ (0, common_1.Global)()
71
+ ], RedisOmCoreModule);
72
+ //# sourceMappingURL=redis-om-core.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-om-core.module.js","sourceRoot":"","sources":["../../src/redis-om/redis-om-core.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAMwB;AACxB,iCAAqC;AAGrC,6DAA+D;AAC/D,4DAA6D;AAItD,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAC5B,MAAM,CAAC,YAAY,CAAC,OAAkC;QACpD,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE1D,OAAO;YACL,SAAS,EAAE;gBACT,GAAG,cAAc;gBACjB;oBACE,UAAU,EAAE,KAAK,EAAE,GAAyB,EAAE,EAAE;wBAC9C,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;wBAC7C,MAAM,WAAW,GAAG,IAAA,oBAAY,EAAC,SAAS,CAAC,CAAC;wBAC5C,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;wBAE5B,OAAO,WAAW,CAAC;oBACrB,CAAC;oBACD,MAAM,EAAE,CAAC,4CAAuB,CAAC;oBACjC,OAAO,EAAE,IAAA,mCAAkB,GAAE;iBAC9B;aACF;YACD,OAAO,EAAE,CAAC,IAAA,mCAAkB,GAAE,CAAC;YAC/B,MAAM,EAAE,mBAAiB;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAA6B;QAC1C,MAAM,yBAAyB,GAAa;YAC1C,UAAU,EAAE,KAAK,IAAI,EAAE;gBACrB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;gBACzD,MAAM,WAAW,GAAG,IAAA,oBAAY,EAAC,SAAS,CAAC,CAAC;gBAC5C,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;gBAE5B,OAAO,WAAW,CAAC;YACrB,CAAC;YACD,OAAO,EAAE,IAAA,mCAAkB,GAAE;SAC9B,CAAC;QAEF,OAAO;YACL,SAAS,EAAE,CAAC,yBAAyB,CAAC;YACtC,OAAO,EAAE,CAAC,yBAAyB,CAAC;YACpC,MAAM,EAAE,mBAAiB;SAC1B,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,OAAkC;QAElC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO;gBACL;oBACE,OAAO,EAAE,4CAAuB;oBAChC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;iBAC7B;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,qBAAqB,KAAI,CAAC;CACjC,CAAA;AA5DY,8CAAiB;4BAAjB,iBAAiB;IAF7B,IAAA,eAAM,EAAC,EAAE,CAAC;IACV,IAAA,eAAM,GAAE;GACI,iBAAiB,CA4D7B"}
@@ -0,0 +1,3 @@
1
+ export declare const REDIS_OM_SCHEMA_METADATA = "redis_om:schema_metadata";
2
+ export declare const REDIS_OM_PROP_METADATA = "redis_om:prop_metadata";
3
+ export declare const REDIS_OM_MODULE_OPTIONS = "redis_om:module_options";