zync-nest-data-module 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 (84) hide show
  1. package/README.md +672 -0
  2. package/dist/backup/backup.config.d.ts +4 -0
  3. package/dist/backup/backup.config.js +84 -0
  4. package/dist/backup/backup.config.js.map +1 -0
  5. package/dist/backup/backup.interface.d.ts +21 -0
  6. package/dist/backup/backup.interface.js +3 -0
  7. package/dist/backup/backup.interface.js.map +1 -0
  8. package/dist/backup/backup.module.d.ts +2 -0
  9. package/dist/backup/backup.module.js +24 -0
  10. package/dist/backup/backup.module.js.map +1 -0
  11. package/dist/backup/backup.service.d.ts +19 -0
  12. package/dist/backup/backup.service.js +229 -0
  13. package/dist/backup/backup.service.js.map +1 -0
  14. package/dist/backup/index.d.ts +4 -0
  15. package/dist/backup/index.js +21 -0
  16. package/dist/backup/index.js.map +1 -0
  17. package/dist/database/database.module.d.ts +2 -0
  18. package/dist/database/database.module.js +34 -0
  19. package/dist/database/database.module.js.map +1 -0
  20. package/dist/database/database.repository.d.ts +62 -0
  21. package/dist/database/database.repository.js +259 -0
  22. package/dist/database/database.repository.js.map +1 -0
  23. package/dist/database/database.scheme.d.ts +45 -0
  24. package/dist/database/database.scheme.js +187 -0
  25. package/dist/database/database.scheme.js.map +1 -0
  26. package/dist/database/database.service.d.ts +7 -0
  27. package/dist/database/database.service.js +39 -0
  28. package/dist/database/database.service.js.map +1 -0
  29. package/dist/database/database.sync.d.ts +10 -0
  30. package/dist/database/database.sync.js +44 -0
  31. package/dist/database/database.sync.js.map +1 -0
  32. package/dist/database/database.transaction.d.ts +17 -0
  33. package/dist/database/database.transaction.js +101 -0
  34. package/dist/database/database.transaction.js.map +1 -0
  35. package/dist/database/database.uniqueId.d.ts +25 -0
  36. package/dist/database/database.uniqueId.js +68 -0
  37. package/dist/database/database.uniqueId.js.map +1 -0
  38. package/dist/database/database.utils.d.ts +10 -0
  39. package/dist/database/database.utils.js +119 -0
  40. package/dist/database/database.utils.js.map +1 -0
  41. package/dist/database/index.d.ts +8 -0
  42. package/dist/database/index.js +25 -0
  43. package/dist/database/index.js.map +1 -0
  44. package/dist/index.d.ts +3 -0
  45. package/dist/index.js +20 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/service/index.d.ts +1 -0
  48. package/dist/service/index.js +18 -0
  49. package/dist/service/index.js.map +1 -0
  50. package/dist/service/service.d.ts +40 -0
  51. package/dist/service/service.js +182 -0
  52. package/dist/service/service.js.map +1 -0
  53. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  54. package/libs/src/app.controller.ts +84 -0
  55. package/libs/src/app.module.ts +31 -0
  56. package/libs/src/backup/backup.config.ts +45 -0
  57. package/libs/src/backup/backup.interface.ts +21 -0
  58. package/libs/src/backup/backup.module.ts +11 -0
  59. package/libs/src/backup/backup.service.ts +283 -0
  60. package/libs/src/backup/index.ts +4 -0
  61. package/libs/src/database/database.module.ts +26 -0
  62. package/libs/src/database/database.repository.ts +358 -0
  63. package/libs/src/database/database.scheme.ts +128 -0
  64. package/libs/src/database/database.service.ts +36 -0
  65. package/libs/src/database/database.sync.ts +61 -0
  66. package/libs/src/database/database.transaction.ts +101 -0
  67. package/libs/src/database/database.uniqueId.ts +59 -0
  68. package/libs/src/database/database.utils.ts +99 -0
  69. package/libs/src/database/index.ts +8 -0
  70. package/libs/src/index.ts +3 -0
  71. package/libs/src/main.ts +62 -0
  72. package/libs/src/service/index.ts +1 -0
  73. package/libs/src/service/service.ts +201 -0
  74. package/libs/src/test/test.dto.ts +41 -0
  75. package/libs/src/test/test.module.ts +20 -0
  76. package/libs/src/test/test.repository.ts +44 -0
  77. package/libs/src/test/test.resolver.ts +44 -0
  78. package/libs/src/test/test.schema.ts +21 -0
  79. package/libs/src/test/test.service.ts +19 -0
  80. package/libs/tsconfig.lib.json +19 -0
  81. package/nest-cli.json +16 -0
  82. package/package.json +89 -0
  83. package/tsconfig.json +29 -0
  84. package/update-links.js +159 -0
@@ -0,0 +1,59 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { InjectModel, Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
3
+ import { Document, Types } from "mongoose";
4
+ import { SoftDeleteModel } from "mongoose-delete";
5
+
6
+ @Schema({ collection: "unique_ids" })
7
+ export class UniqueId {
8
+ _id: string;
9
+ @Prop({ unique: true })
10
+ key: string;
11
+ @Prop()
12
+ sequence_value: number;
13
+ }
14
+ export type UniqueIdDocument = UniqueId & Document;
15
+
16
+ export const UniqueIdSchema = SchemaFactory.createForClass(UniqueId);
17
+
18
+ export type UniqueKeyTypes = "users" | "uniqueId";
19
+
20
+ @Injectable({})
21
+ export class ApUniqueIdGenerator {
22
+ constructor(
23
+ @InjectModel(UniqueId.name)
24
+ private model: SoftDeleteModel<UniqueIdDocument>
25
+ ) {
26
+ this.seed();
27
+ }
28
+
29
+ public async getNextUniqueId(key: string = "uniqueId"): Promise<number> {
30
+ const result = await this.model.findOneAndUpdate(
31
+ { key },
32
+ { $inc: { sequence_value: 1 } },
33
+ { returnDocument: "after", upsert: true }
34
+ );
35
+
36
+ if (!result) {
37
+ throw new Error("Failed to generate unique ID");
38
+ }
39
+
40
+ return result.sequence_value;
41
+ }
42
+
43
+ public getObjectId(): string {
44
+ return new Types.ObjectId().toString();
45
+ }
46
+
47
+ public async seed(): Promise<void> {
48
+ const keys = [{ key: "uniqueId", sequence_value: 1001 }];
49
+
50
+ for await (const key of keys) {
51
+ const exist = await this.model.findOne({ key: key.key });
52
+
53
+ if (exist) {
54
+ continue;
55
+ }
56
+ await this.model.create(key);
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,99 @@
1
+ import moment from "moment";
2
+ import { ObjectId } from "mongodb";
3
+ import * as mongoose from "mongoose";
4
+ import { Connection, Schema } from "mongoose";
5
+
6
+ const mapToObjectIds = <T>(query: Partial<T>): T => {
7
+ try {
8
+ const mapVal = (val: any): any => {
9
+ if (Array.isArray(val)) {
10
+ return val.map(mapVal); // Recursively map each array element
11
+ } else if (val && typeof val === "object" && !ObjectId.isValid(val)) {
12
+ return mapToObjectIds(val); // Recursively process nested objects
13
+ } else if (
14
+ val &&
15
+ ObjectId.isValid(val?.toString()) &&
16
+ new ObjectId(val?.toString())?.toString() === val
17
+ ) {
18
+ return new ObjectId(val?.toString()); // Convert valid ObjectId strings
19
+ }
20
+ return val; // Return as-is if no conversion needed
21
+ };
22
+
23
+ const mappedQuery: any = { ...query };
24
+ Object.keys(mappedQuery).forEach((key) => {
25
+ mappedQuery[key] = mapVal(mappedQuery[key]); // Apply transformation
26
+ });
27
+
28
+ return mappedQuery;
29
+ } catch (error) {
30
+ console.error("mapToObjectIds Error:", error);
31
+ // return query; // Return original query in case of error
32
+ }
33
+ };
34
+
35
+ export const DbUtils = {
36
+ mapToObjectIds,
37
+ getOrCreateDiscriminatorModel(
38
+ connection: Connection = mongoose.connection,
39
+ baseModelName: string,
40
+ baseSchema: Schema,
41
+ discriminatorName: string,
42
+ discriminatorSchema: Schema
43
+ ) {
44
+ const getBaseModel = (conn: Connection | typeof mongoose) =>
45
+ conn.models[baseModelName] || conn.model(baseModelName, baseSchema);
46
+
47
+ const BaseModel = connection
48
+ ? getBaseModel(connection)
49
+ : getBaseModel(mongoose);
50
+
51
+ if (
52
+ !BaseModel.discriminators ||
53
+ !BaseModel.discriminators[discriminatorName]
54
+ ) {
55
+ return BaseModel.discriminator(discriminatorName, discriminatorSchema);
56
+ }
57
+
58
+ return connection
59
+ ? connection.models[discriminatorName] ||
60
+ connection.model(discriminatorName)
61
+ : mongoose.models[discriminatorName] || mongoose.model(discriminatorName);
62
+ },
63
+ };
64
+
65
+ export const SchemeUtil = {
66
+ toObjectId: (value: string) => {
67
+ try {
68
+ if (Array.isArray(value)) {
69
+ return value.map((v) =>
70
+ mongoose.Types.ObjectId.isValid(v)
71
+ ? new mongoose.Types.ObjectId(v)
72
+ : v
73
+ );
74
+ } else if (mongoose.Types.ObjectId.isValid(value)) {
75
+ return new mongoose.Types.ObjectId(value);
76
+ } else if (typeof value === "string") {
77
+ return new mongoose.Types.ObjectId(value);
78
+ }
79
+ } catch (error) {
80
+ return value;
81
+ }
82
+ },
83
+ toCurrentDate: (value: number | string) => {
84
+ if (!value) {
85
+ return moment().valueOf();
86
+ }
87
+
88
+ if (typeof value === "number" && !Number.isNaN(value)) {
89
+ return value;
90
+ }
91
+
92
+ const momentDate = moment(value);
93
+ if (momentDate.isValid()) {
94
+ return momentDate.valueOf();
95
+ }
96
+
97
+ return moment().valueOf();
98
+ },
99
+ };
@@ -0,0 +1,8 @@
1
+ export * from './database.scheme';
2
+ export * from './database.repository';
3
+ export * from './database.transaction';
4
+ export * from './database.module';
5
+ export * from './database.uniqueId';
6
+ export * from './database.service';
7
+ export * from './database.utils';
8
+ export * from './database.sync';
@@ -0,0 +1,3 @@
1
+ export * from "./backup";
2
+ export * from "./database";
3
+ export * from "./service";
@@ -0,0 +1,62 @@
1
+ import { NestFactory } from "@nestjs/core";
2
+ import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
3
+ import { ValidationPipe } from "@nestjs/common";
4
+ import { ApDbModule } from "./app.module";
5
+
6
+ async function bootstrap() {
7
+ const app = await NestFactory.create(ApDbModule);
8
+
9
+ // Enable CORS
10
+ app.enableCors({
11
+ origin: true,
12
+ credentials: true,
13
+ });
14
+
15
+ // // Global validation pipe
16
+ // app.useGlobalPipes(
17
+ // new ValidationPipe({
18
+ // transform: true,
19
+ // whitelist: true,
20
+ // forbidNonWhitelisted: true,
21
+ // })
22
+ // );
23
+
24
+ // Swagger configuration
25
+ const config = new DocumentBuilder()
26
+ .setTitle("Zync Nest Database API")
27
+ .setDescription("API documentation for Zync Nest Database")
28
+ .setVersion("1.0.23")
29
+ .addTag("Database", "Database endpoints for Zync Nest Database")
30
+ .build();
31
+
32
+ const document = SwaggerModule.createDocument(app, config);
33
+ SwaggerModule.setup("api", app, document, {
34
+ customSiteTitle: "Zync Nest Database API",
35
+ customfavIcon: "https://nestjs.com/img/logo-small.svg",
36
+ customJs: [
37
+ "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-bundle.js",
38
+ "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-standalone-preset.js",
39
+ ],
40
+ customCssUrl: [
41
+ "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui.min.css",
42
+ ],
43
+ });
44
+
45
+ const port = process.env.app_port || 3000;
46
+ await app.listen(port);
47
+
48
+ console.log(
49
+ `🚀 Zync Nest Database server is running on: http://localhost:${port}`
50
+ );
51
+ console.log(
52
+ `📚 Swagger documentation available at: http://localhost:${port}/api`
53
+ );
54
+ console.log(
55
+ `🔍 Health check available at: http://localhost:${port}/test/health`
56
+ );
57
+ }
58
+
59
+ bootstrap().catch((error) => {
60
+ console.error("Failed to start the application:", error);
61
+ process.exit(1);
62
+ });
@@ -0,0 +1 @@
1
+ export * from "./service";
@@ -0,0 +1,201 @@
1
+ import { forwardRef, Inject } from "@nestjs/common";
2
+ import { AbstractBaseRepository, IPageParams, TransactionManager, TransactionSession } from "../database";
3
+
4
+ class BaseService<T> {
5
+ constructor(
6
+ @Inject(forwardRef(() => AbstractBaseRepository))
7
+ protected readonly repository: AbstractBaseRepository<any>
8
+ ) {}
9
+
10
+ public async create(data: Partial<T> | T): Promise<T> {
11
+ return await this.repository.create(data);
12
+ }
13
+
14
+ public async update(_id: string, data: Partial<T> | T): Promise<T> {
15
+ return await this.repository.update(_id, data);
16
+ }
17
+
18
+ public async updateMany(query: Partial<T>, model: Partial<T>): Promise<void> {
19
+ return await this.repository.updateMany(query, model);
20
+ }
21
+
22
+ public async findById(_id: string): Promise<T> {
23
+ return await this.repository.findById(_id);
24
+ }
25
+
26
+ public async findOne(query: Partial<T>): Promise<T> {
27
+ return await this.repository.findOne(query);
28
+ }
29
+
30
+ public async find(query: Partial<T>): Promise<T[]> {
31
+ return await this.repository.find(query);
32
+ }
33
+
34
+ public async findLast(query?: Partial<T>): Promise<T> {
35
+ return await this.repository.findLast(query);
36
+ }
37
+
38
+ public async delete(_id: string): Promise<Boolean> {
39
+ await this.repository.delete(_id);
40
+ return true;
41
+ }
42
+
43
+ public async deleteMany(query: Partial<T>): Promise<Boolean> {
44
+ await this.repository.deleteMany(query);
45
+ return true;
46
+ }
47
+
48
+ public async page(
49
+ query: Partial<T> & IPageParams
50
+ ): Promise<{ totalRecords: number; data: Array<T> }> {
51
+ return await this.repository.page(query);
52
+ }
53
+
54
+ public async count(query: Partial<T>): Promise<number> {
55
+ return this.repository.count(query);
56
+ }
57
+ }
58
+
59
+ export abstract class AbstractBaseService<T> extends BaseService<T> {
60
+ private _session: TransactionSession;
61
+ constructor(
62
+ @Inject(forwardRef(() => AbstractBaseRepository))
63
+ protected readonly repository: AbstractBaseRepository<any>,
64
+ @Inject(forwardRef(() => TransactionManager))
65
+ public readonly transactionManager: TransactionManager
66
+ ) {
67
+ super(repository);
68
+ }
69
+
70
+ protected abstract setSession(session: any): void;
71
+
72
+ public get session(): TransactionSession {
73
+ return this._session;
74
+ }
75
+
76
+ public set session(v: TransactionSession) {
77
+ this._session = v;
78
+ this.repository.session = this._session;
79
+ }
80
+
81
+ public get sessionName(): string {
82
+ return this.transactionManager.sessionName;
83
+ }
84
+
85
+ public async withRetryTransaction(
86
+ sessionName: string,
87
+ operations: () => Promise<T>,
88
+ retries: number = 3
89
+ ): Promise<T> {
90
+ if (!process.env.mongodb_transaction_enabled) {
91
+ return await operations();
92
+ }
93
+
94
+ try {
95
+ await this.startSession(sessionName);
96
+
97
+ let attempt = 0;
98
+ while (attempt < retries) {
99
+ try {
100
+ const op = await operations();
101
+ await this.commitSession(sessionName);
102
+ return op;
103
+ } catch (error) {
104
+ if (this.isRetryableError(error)) {
105
+ console.log(`[TransactionManager] Retrying transaction...`);
106
+ await this.delay(1000 * (attempt + 1)); // Exponential backoff
107
+ await this.transactionManager.abortTransaction();
108
+ await this.startSession(sessionName, true);
109
+ } else {
110
+ await this.abortSession();
111
+ throw error;
112
+ }
113
+ }
114
+ attempt++;
115
+ }
116
+ } catch (error) {
117
+ console.log(`[TransactionManager] Error in transaction`, error);
118
+ await this.abortSession();
119
+ throw error;
120
+ } finally {
121
+ console.log(`[TransactionManager] Finally block`);
122
+ if (this.transactionManager.sessionName == sessionName) {
123
+ await this.endSession();
124
+ }
125
+ }
126
+ }
127
+
128
+ private isRetryableError(error: any): boolean {
129
+ return (
130
+ error.code === 112 // WriteConflict
131
+ );
132
+ }
133
+
134
+ private delay(ms: number): Promise<void> {
135
+ return new Promise((resolve) => setTimeout(resolve, ms));
136
+ }
137
+
138
+ protected async startSession(sessionName: string, force: boolean = false) {
139
+ if (this.transactionManager.sessionName && !force) {
140
+ this.session = this._session;
141
+ this.repository.session = this._session;
142
+ console.log(
143
+ `[TransactionManager] startSession ${this.transactionManager.sessionName} - ${sessionName} is already active`
144
+ );
145
+ return;
146
+ }
147
+
148
+ console.log(`[TransactionManager] startSession ${sessionName} is started`);
149
+
150
+ this._session = await this.transactionManager.startTransaction();
151
+ this.repository.session = this._session;
152
+ this.transactionManager.sessionName = sessionName;
153
+ this.setSession(this._session);
154
+ }
155
+
156
+ protected async commitSession(sessionName: string) {
157
+ if (this.transactionManager.sessionName !== sessionName) {
158
+ console.log(
159
+ `[TransactionManager] Session ${this.transactionManager.sessionName} - ${sessionName} is not active`
160
+ );
161
+ return;
162
+ }
163
+
164
+ await this.transactionManager.commitTransaction();
165
+ this._session = null;
166
+ this.repository.session = null;
167
+ this.transactionManager.sessionName = undefined;
168
+ this.setSession(null);
169
+ }
170
+
171
+ public async abortSession() {
172
+ await this.transactionManager.abortTransaction();
173
+ this._session = null;
174
+ this.repository.session = null;
175
+ this.transactionManager.sessionName = undefined;
176
+ this.setSession(null);
177
+ }
178
+
179
+ public async endSession() {
180
+ await this.transactionManager.endTransaction();
181
+ this._session = null;
182
+ this.repository.session = null;
183
+ this.transactionManager.sessionName = undefined;
184
+ this.setSession(null);
185
+ }
186
+
187
+ protected getObjectId(): string | any {
188
+ return this.repository.getObjectId();
189
+ }
190
+
191
+ protected toObjectId(value: string | any): any {
192
+ return this.repository.toObjectId(value);
193
+ }
194
+
195
+ public async checkExist(id: any): Promise<void> {
196
+ const exist = await this.repository.findOne(id);
197
+ if (!exist) {
198
+ throw new Error("Record does not exist");
199
+ }
200
+ }
201
+ }
@@ -0,0 +1,41 @@
1
+ import { Field, InputType, ObjectType, PartialType } from "@nestjs/graphql";
2
+
3
+ @ObjectType()
4
+ export class Test {
5
+ @Field({ nullable: true })
6
+ name: string;
7
+ }
8
+
9
+ @InputType()
10
+ export class TestCommonInput {
11
+ @Field({ nullable: true })
12
+ name: string;
13
+ }
14
+
15
+ @InputType()
16
+ export class CreateTestInput extends TestCommonInput {}
17
+
18
+ @InputType()
19
+ export class UpdateTestInput extends PartialType(TestCommonInput) {}
20
+
21
+ @InputType()
22
+ export class TestQueryInput {
23
+ @Field({ nullable: true })
24
+ keyword: string;
25
+ }
26
+
27
+ @ObjectType()
28
+ export class TestPageResult {
29
+ @Field({})
30
+ totalRecords: number;
31
+ @Field((type) => [Test])
32
+ data: Array<Test>;
33
+ }
34
+
35
+ @InputType()
36
+ export class TestPageInput extends TestQueryInput {
37
+ @Field({})
38
+ skip: number;
39
+ @Field({})
40
+ take: number;
41
+ }
@@ -0,0 +1,20 @@
1
+ import { forwardRef, Module } from "@nestjs/common";
2
+ import { MongooseModule } from "@nestjs/mongoose";
3
+ import { TestRepository } from "./test.repository";
4
+ import { TestResolver } from "./test.resolver";
5
+ import { Test, TestSchema } from "./test.schema";
6
+ import { TestService } from "./test.service";
7
+
8
+ const TestMongooseModule = MongooseModule.forFeature([
9
+ {
10
+ name: Test.name,
11
+ schema: TestSchema,
12
+ },
13
+ ]);
14
+
15
+ @Module({
16
+ imports: [TestMongooseModule],
17
+ providers: [TestRepository, TestService, TestResolver],
18
+ exports: [TestService],
19
+ })
20
+ export class TestModule {}
@@ -0,0 +1,44 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { InjectModel } from "@nestjs/mongoose";
3
+ import moment from "moment";
4
+ import { SoftDeleteModel } from "mongoose-delete";
5
+ import { AbstractBaseRepository } from "../database/database.repository";
6
+ import { Test, TestDocument, TestSchema } from "./test.schema";
7
+
8
+ @Injectable()
9
+ export class TestRepository extends AbstractBaseRepository<TestDocument> {
10
+ constructor(
11
+ @InjectModel(Test.name)
12
+ public dbModel: SoftDeleteModel<TestDocument>
13
+ ) {
14
+ super(dbModel);
15
+ }
16
+
17
+ public async mapData(data: any, isCreate: boolean): Promise<TestDocument> {
18
+ const payload: any = data;
19
+
20
+ if (isCreate) {
21
+ payload.ref = payload.ref || (await this.generateRef());
22
+ payload.createdBy = payload.createdBy;
23
+ payload.createdAt = payload.createdAt
24
+ ? moment(payload.createdAt).valueOf()
25
+ : moment().valueOf();
26
+ } else {
27
+ payload.updatedBy = payload.updatedBy;
28
+ payload.updatedAt = payload.updatedAt
29
+ ? moment(payload.updatedAt).valueOf()
30
+ : moment().valueOf();
31
+ }
32
+ return this.mapIds(payload);
33
+ }
34
+
35
+ protected buildQuery(query: Partial<TestDocument>) {
36
+ const andConditions: any[] = [];
37
+
38
+ this.schemaKeysQuery(TestSchema, { query }, (condition: any) => {
39
+ andConditions.push(condition);
40
+ });
41
+
42
+ return this.cleanupQuery(andConditions);
43
+ }
44
+ }
@@ -0,0 +1,44 @@
1
+ import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
2
+ import {
3
+ CreateTestInput,
4
+ Test,
5
+ TestPageInput,
6
+ TestPageResult,
7
+ TestQueryInput,
8
+ UpdateTestInput,
9
+ } from "./test.dto";
10
+ import { TestService } from "./test.service";
11
+
12
+ @Resolver(() => Test)
13
+ export class TestResolver {
14
+ constructor(private readonly testSvc: TestService) {}
15
+
16
+ @Mutation((returns) => Test, { name: "createTest" })
17
+ public async create(@Args("test") testSvc: CreateTestInput) {
18
+ return this.testSvc.create(testSvc as any);
19
+ }
20
+
21
+ @Mutation((returns) => Test, { name: "updateTest" })
22
+ public async update(
23
+ @Args("_id") id: string,
24
+ @Args("test") test: UpdateTestInput
25
+ ) {
26
+ return this.testSvc.update(id, { ...test } as any);
27
+ }
28
+
29
+ @Mutation((returns) => Boolean, { name: "deleteTest" })
30
+ public async delete(@Args("_id") id: string) {
31
+ await this.testSvc.delete(id);
32
+ return true;
33
+ }
34
+
35
+ @Query((returns) => Test, { name: "findOneTest" })
36
+ public async findOne(@Args("test") test: TestQueryInput) {
37
+ return this.testSvc.findOne(test as any);
38
+ }
39
+
40
+ @Query((returns) => TestPageResult, { name: "testPage" })
41
+ public async page(@Args("page") page: TestPageInput) {
42
+ return this.testSvc.page({ ...page } as any);
43
+ }
44
+ }
@@ -0,0 +1,21 @@
1
+ import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
2
+ import { Document } from "mongoose";
3
+ import { BaseSchema, IPageParams } from "../database/database.scheme";
4
+ export type TestDocument = Test & Document;
5
+
6
+ @Schema({ collection: "tests" })
7
+ export class Test extends BaseSchema {
8
+ @Prop({ required: true })
9
+ name: string;
10
+ }
11
+
12
+ export const TestSchema = SchemaFactory.createForClass(Test);
13
+
14
+ export class TestQuery extends Test {
15
+ keyword?: string;
16
+ }
17
+
18
+ export class PageParams extends TestQuery implements IPageParams {
19
+ skip: number;
20
+ take: number;
21
+ }
@@ -0,0 +1,19 @@
1
+ import { forwardRef, Inject, Injectable } from "@nestjs/common";
2
+ import { TestRepository } from "./test.repository";
3
+ import { Test } from "./test.schema";
4
+ import { TransactionManager } from "../database";
5
+ import { AbstractBaseService } from "../service/service";
6
+
7
+ @Injectable()
8
+ export class TestService extends AbstractBaseService<Test> {
9
+ constructor(
10
+ @Inject(forwardRef(() => TestRepository))
11
+ private readonly testRepo: TestRepository,
12
+ @Inject(forwardRef(() => TransactionManager))
13
+ transactionManager: TransactionManager
14
+ ) {
15
+ super(testRepo, transactionManager);
16
+ }
17
+
18
+ protected setSession(session: any): void {}
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "outDir": "../dist"
6
+ },
7
+ "include": [
8
+ "src/database/**/*",
9
+ "src/backup/**/*",
10
+ "src/service/**/*",
11
+ "src/index.ts",
12
+ ],
13
+ "exclude": [
14
+ "node_modules",
15
+ "dist",
16
+ "test",
17
+ "**/*spec.ts",
18
+ ]
19
+ }
package/nest-cli.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "projects": {
3
+ ".": {
4
+ "type": "library",
5
+ "root": "libs",
6
+ "entryFile": "index",
7
+ "sourceRoot": "libs/src",
8
+ "compilerOptions": {
9
+ "tsConfigPath": "libs/tsconfig.lib.json"
10
+ }
11
+ }
12
+ },
13
+ "compilerOptions": {
14
+ "webpack": true
15
+ }
16
+ }