diff --git a/package-lock.json b/package-lock.json index c627cf73..bf7fa57a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,11 +16,11 @@ "@nestjs/event-emitter": "3.1.0", "@nestjs/jwt": "11.0.2", "@nestjs/mongoose": "11.0.3", - "@nestjs/platform-express": "11.1.27", + "@nestjs/platform-express": "11.2.6", "@nestjs/platform-socket.io": "^11.2.3", "@nestjs/platform-ws": "11.1.27", "@nestjs/schedule": "6.1.3", - "@nestjs/swagger": "11.4.4", + "@nestjs/swagger": "11.4.7", "@nestjs/websockets": "11.1.27", "argon2": "0.44.0", "bull": "4.16.5", @@ -36,7 +36,7 @@ "lodash": "4.18.1", "migrate-mongo": "^14.0.7", "mongodb": "6.20.0", - "mongoose": "8.19.4", + "mongoose": "8.24.4", "mqtt": "5.14.1", "rxjs": "7.8.2", "socket.io": "^4.8.3", @@ -51,7 +51,7 @@ "@types/express": "5.0.5", "@types/jest": "^30.0.0", "@types/lodash": "4.17.20", - "@types/multer": "2.0.0", + "@types/multer": "2.3.0", "@types/node": "24.10.1", "@types/supertest": "^7.2.1", "@types/ws": "8.18.1", @@ -2464,14 +2464,14 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.27", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.27.tgz", - "integrity": "sha512-0ZFhz6H6EdGh4xQVbUNwjoAwBuz73P7FvUAl67h9CTdMqQlJDaQYJApBv8pKfVZ1fGjMCbl0m9DcC6pXaZPWSQ==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.2.6.tgz", + "integrity": "sha512-jPypI/+aueizkYG2Bw2kg8GaNsWE7ekFBSQ/Rwet7wEdBA/+q2FA364UbDabqjlR7C3VSNHmP/JXh+8+jXyDOw==", "license": "MIT", "dependencies": { "cors": "2.8.6", "express": "5.2.1", - "multer": "2.1.1", + "multer": "2.4.0", "path-to-regexp": "8.4.2", "tslib": "2.8.1" }, @@ -2662,20 +2662,20 @@ } }, "node_modules/@nestjs/swagger": { - "version": "11.4.4", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.4.4.tgz", - "integrity": "sha512-VaIo1ruV2G7b+f2zPzkBSUNy9a/WQ9sg8TLKhWlrTfg4O6U10M/PA7Xi6XMXadOVhwOqoesijba8jH3i/3adrA==", + "version": "11.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.4.7.tgz", + "integrity": "sha512-QyDYnmfP4IRucgmtQxMqzgRBdWtjFoDp8eFvvgf92+3wdLCL+Q0xOFO1948j/ntW/Wi7qT2dyck6ka8ADzPWQQ==", "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.16.0", "@nestjs/mapped-types": "2.1.1", - "js-yaml": "4.1.1", + "js-yaml": "5.3.0", "lodash": "4.18.1", "path-to-regexp": "8.4.2", - "swagger-ui-dist": "5.32.6" + "swagger-ui-dist": "5.32.13" }, "peerDependencies": { - "@fastify/static": "^8.0.0 || ^9.0.0", + "@fastify/static": "^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/common": "^11.0.1", "@nestjs/core": "^11.0.1", "class-transformer": "*", @@ -2694,6 +2694,28 @@ } } }, + "node_modules/@nestjs/swagger/node_modules/js-yaml": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.3.0.tgz", + "integrity": "sha512-muutsYr+e2+d3rTgUGslq5rxbBlUy3cJ61IsHag2QNDQV+7zXWjkUpmALIajhrlLlrgRUiymj6U3zUr/TMK84Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, "node_modules/@nestjs/testing": { "version": "11.1.27", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.27.tgz", @@ -3195,9 +3217,9 @@ "license": "MIT" }, "node_modules/@types/multer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.0.0.tgz", - "integrity": "sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.3.0.tgz", + "integrity": "sha512-i7STIm9V4K2MPH4ZYMtrZAwNxs3kglk2LgleaTuB9pUXgADBcQYQuYMd7+6xgTIxfoggIkFA/DkkvycdZpIARA==", "dev": true, "license": "MIT", "dependencies": { @@ -8444,6 +8466,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -9179,9 +9202,9 @@ } }, "node_modules/mongoose": { - "version": "8.19.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.19.4.tgz", - "integrity": "sha512-yiY/Wv6FUYDQ4kBN1RQHiYuayQS4k+yzytj4nctMmQiBIXLfJqvw6fRgmvw1rIOmShp7iAbpNt7s2s6TyVOSyA==", + "version": "8.24.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.24.4.tgz", + "integrity": "sha512-DoV8hYy5ssoh/j99rhYzeS2BLLcLJZ+EGQYfe/Ln+yMorBy0wgKdlwJBj59zJ1N0MnEKQypbeqUYFB0FVThmYg==", "license": "MIT", "dependencies": { "bson": "^6.10.4", @@ -9308,14 +9331,13 @@ } }, "node_modules/multer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz", - "integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.4.0.tgz", + "integrity": "sha512-7dqa0ZcFfzbefdTuIkzOSMvZWC0J7FLqBOjJUZvDCXShIURWKxAyTT1wHhnE5q19c7jOJf43IYYKjBmZVZmvhg==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", - "concat-stream": "^2.0.0", "type-is": "^1.6.18" }, "engines": { @@ -11354,9 +11376,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.32.6", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.32.6.tgz", - "integrity": "sha512-75ttZNaYCLoFPnozPZcTUU6mS3wKT8l7WLjU5zJSHFeJa23i5vtnze6IiCl4jDMPeQTXVXIgovq4M11NNfQvSA==", + "version": "5.32.13", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.32.13.tgz", + "integrity": "sha512-qQobzb3DeC2LeK0j3E8812Ef4aIq1y9flJxvZkimkqUC/w4u7wS+yCc+VakqGJLweUUBrI24effhwo8OsAvNAw==", "license": "Apache-2.0", "dependencies": { "@scarf/scarf": "=1.4.0" diff --git a/package.json b/package.json index 1f606140..ae59c291 100644 --- a/package.json +++ b/package.json @@ -35,11 +35,11 @@ "@nestjs/event-emitter": "3.1.0", "@nestjs/jwt": "11.0.2", "@nestjs/mongoose": "11.0.3", - "@nestjs/platform-express": "11.1.27", + "@nestjs/platform-express": "11.2.6", "@nestjs/platform-socket.io": "^11.2.3", "@nestjs/platform-ws": "11.1.27", "@nestjs/schedule": "6.1.3", - "@nestjs/swagger": "11.4.4", + "@nestjs/swagger": "11.4.7", "@nestjs/websockets": "11.1.27", "argon2": "0.44.0", "bull": "4.16.5", @@ -55,7 +55,7 @@ "lodash": "4.18.1", "migrate-mongo": "^14.0.7", "mongodb": "6.20.0", - "mongoose": "8.19.4", + "mongoose": "8.24.4", "mqtt": "5.14.1", "rxjs": "7.8.2", "socket.io": "^4.8.3", @@ -70,7 +70,7 @@ "@types/express": "5.0.5", "@types/jest": "^30.0.0", "@types/lodash": "4.17.20", - "@types/multer": "2.0.0", + "@types/multer": "2.3.0", "@types/node": "24.10.1", "@types/supertest": "^7.2.1", "@types/ws": "8.18.1", diff --git a/src/clanInventory/item/item.schema.ts b/src/clanInventory/item/item.schema.ts index 831098b2..3371273e 100644 --- a/src/clanInventory/item/item.schema.ts +++ b/src/clanInventory/item/item.schema.ts @@ -61,7 +61,7 @@ export class Item { stock_id: Stock; @Prop({ type: MongooseSchema.Types.ObjectId, ref: ModelName.ROOM }) - room_id: Room; + room_id: Room | string; @ExtractField() _id: string; diff --git a/src/common/service/basicService/BasicService.ts b/src/common/service/basicService/BasicService.ts index 7b1f31e0..8c42ed3f 100644 --- a/src/common/service/basicService/BasicService.ts +++ b/src/common/service/basicService/BasicService.ts @@ -1,6 +1,8 @@ import { AnyBulkWriteOperation, + AnyKeys, Error, + HydratedDocument, Model, MongooseBulkWriteOptions, UpdateQuery, @@ -19,6 +21,7 @@ import { TIServiceUpdateByIdOptions, TIServiceUpdateManyOptions, TIServiceUpdateOneOptions, + TServiceBulkWriteOperation, TReadByIdOptions, } from './IService'; import ServiceError from './ServiceError'; @@ -32,27 +35,39 @@ import { hasUnsafeMongoUpdateKey } from '../../function/validateMongoUpdate'; * * In case of any errors occurred class methods will return an array of ServiceErrors */ -export default class BasicService implements IService { +export default class BasicService + implements IService +{ + private readonly model: Model; + /** * * @param model DB model class to query. Can also be injected with @InjectModel() by mongoose */ - constructor(private readonly model: Model) {} + constructor(model: Model) { + this.model = model as Model; + } - async createOne( + async createOne< + TInput extends AnyKeys = AnyKeys, + TOutput = HydratedDocument, + >( input: TInput, options?: TIServiceCreateOneOptions, ): Promise> { try { const data = await this.model.create([input], options); - return [data[0], null]; + return [data[0] as TOutput, null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async createMany( + async createMany< + TInput extends AnyKeys = AnyKeys, + TOutput = HydratedDocument, + >( input: TInput[], options?: TIServiceCreateManyOptions, ): Promise> { @@ -61,14 +76,14 @@ export default class BasicService implements IService { ? { ...options, ordered: true } : options; const data = await this.model.create(input, createOptions); - return [data, null]; + return [data as TOutput[], null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async readOneById( + async readOneById>( _id: string, options?: TReadByIdOptions, ): Promise> { @@ -95,14 +110,14 @@ export default class BasicService implements IService { ], ]; - return [resp, null]; + return [resp as unknown as TOutput, null]; } catch (error: any) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async readOne( + async readOne>( options: TIServiceReadOneOptions, ): Promise> { try { @@ -125,14 +140,14 @@ export default class BasicService implements IService { ], ]; - return [resp, null]; + return [resp as unknown as TOutput, null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async readMany( + async readMany>( options?: TIServiceReadManyOptions, ): Promise> { try { @@ -155,14 +170,14 @@ export default class BasicService implements IService { ], ]; - return [resp, null]; + return [resp as TOutput[], null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async updateOneById( + async updateOneById>( _id: string, input: TInput, options?: TIServiceUpdateByIdOptions, @@ -202,7 +217,7 @@ export default class BasicService implements IService { } } - async updateOne( + async updateOne>( input: TInput, options: TIServiceUpdateOneOptions, ): Promise> { @@ -248,7 +263,7 @@ export default class BasicService implements IService { } } - async updateMany( + async updateMany>( input: TInput[], options: TIServiceUpdateManyOptions, ): Promise> { @@ -293,11 +308,11 @@ export default class BasicService implements IService { } } - async findByIdAndUpdate( + async findByIdAndUpdate>( _id: string, - input: UpdateQuery, + input: UpdateQuery, options?: TIServiceUpdateByIdOptions, - ): Promise> { + ): Promise> { try { if (hasUnsafeMongoUpdateKey(input)) { return [ @@ -329,17 +344,17 @@ export default class BasicService implements IService { ], ]; - return [resp, null]; + return [resp as unknown as TOutput, null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; } } - async findOneAndUpdate( - input: UpdateQuery, + async findOneAndUpdate>( + input: UpdateQuery, options: TIServiceFindOneAndUpdate, - ): Promise> { + ): Promise> { try { if (hasUnsafeMongoUpdateKey(input)) { return [ @@ -381,7 +396,7 @@ export default class BasicService implements IService { ], ]; - return [resp, null]; + return [resp as unknown as TOutput, null]; } catch (error) { const errors = convertMongooseToServiceErrors(error); return [null, errors]; @@ -464,12 +479,14 @@ export default class BasicService implements IService { } } - async bulkWrite( - operations: AnyBulkWriteOperation[], + async bulkWrite( + operations: AnyBulkWriteOperation[], options?: MongooseBulkWriteOptions, ): Promise> { try { - const resp = await this.model.bulkWrite(operations, options); + const modelOperations = + operations as unknown as TServiceBulkWriteOperation[]; + const resp = await this.model.bulkWrite(modelOperations, options); if (resp.matchedCount === 0) return [ null, diff --git a/src/common/service/basicService/IService.ts b/src/common/service/basicService/IService.ts index 34bf09ec..3b1fb05b 100644 --- a/src/common/service/basicService/IService.ts +++ b/src/common/service/basicService/IService.ts @@ -1,6 +1,15 @@ import { ModelName } from '../../../common/enum/modelName.enum'; import ServiceError from './ServiceError'; -import { ClientSession, FilterQuery } from 'mongoose'; +import { + AnyBulkWriteOperation, + AnyKeys, + ClientSession, + FilterQuery, + HydratedDocument, + MongooseBulkWriteOptions, + UpdateQuery, +} from 'mongoose'; +import { Document as MongoDocument } from 'mongodb'; export type TIServiceCreateOneOptions = { /** @@ -388,19 +397,25 @@ export type TIServiceDeleteManyOptions = { */ export type IServiceReturn = [TData | null, ServiceError[] | null]; +export type TServiceBulkWriteOperation = + AnyBulkWriteOperation; + /** * Interface for a service class, which provides all basic operations with DB. * * Notice that the class implementing the interface should not throw any errors but return them as a ServiceError array instead. */ -export interface IService { +export interface IService { /** * Add the specified object to the DB. * @param input - The object to add. * @param options - Options for the request. * @returns The added object to the DB with the _id field or a ServiceError array if something went wrong. */ - createOne( + createOne< + TInput extends AnyKeys = AnyKeys, + TOutput = HydratedDocument, + >( input: TInput, options?: TIServiceCreateOneOptions, ): Promise>; @@ -411,7 +426,10 @@ export interface IService { * @param options - Options for the request. * @returns An array of added objects to the DB with _id fields or a ServiceError array if something went wrong. */ - createMany( + createMany< + TInput extends AnyKeys = AnyKeys, + TOutput = HydratedDocument, + >( input: TInput[], options?: TIServiceCreateManyOptions, ): Promise>; @@ -422,7 +440,7 @@ export interface IService { * @param options - Options for the request. * @returns The found object or a ServiceError array if it was not found or something else went wrong. */ - readOneById( + readOneById>( _id: string, options?: TReadByIdOptions, ): Promise>; @@ -434,7 +452,7 @@ export interface IService { * @param options - Options for the request. * @returns The found object or a ServiceError array if it was not found or something else went wrong. */ - readOne( + readOne>( options: TIServiceReadOneOptions, ): Promise>; @@ -443,7 +461,7 @@ export interface IService { * @param options - Options for the request. * @returns An array of found objects or a ServiceError array if none were found or something else went wrong. */ - readMany( + readMany>( options?: TIServiceReadManyOptions, ): Promise>; @@ -454,7 +472,7 @@ export interface IService { * @param options - Options for the request. * @returns _true_ if it was updated successfully, _false_ if nothing was updated for the object, or a ServiceError array if it was not found or something else went wrong. */ - updateOneById( + updateOneById>( _id: string, input: TInput, options?: TIServiceUpdateByIdOptions, @@ -468,7 +486,7 @@ export interface IService { * @param options - Options for the request. * @returns _true_ if it was updated successfully, _false_ if nothing was updated for the object, or a ServiceError array if it was not found or something else went wrong. */ - updateOne( + updateOne>( input: TInput, options: TIServiceUpdateOneOptions, ): Promise>; @@ -479,7 +497,7 @@ export interface IService { * @param options - Options for the request. * @returns _true_ if the objects were updated successfully, _false_ if nothing was updated for the objects, or a ServiceError array if none were found or something else went wrong. */ - updateMany( + updateMany>( input: TInput[], options: TIServiceUpdateManyOptions, ): Promise>; @@ -512,4 +530,9 @@ export interface IService { deleteMany( options: TIServiceDeleteManyOptions, ): Promise>; + + bulkWrite( + operations: AnyBulkWriteOperation[], + options?: MongooseBulkWriteOptions, + ): Promise>; }