diff --git a/apps/mongo-sample/src/app.module.ts b/apps/mongo-sample/src/app.module.ts index 72a3cceb..91742d7c 100644 --- a/apps/mongo-sample/src/app.module.ts +++ b/apps/mongo-sample/src/app.module.ts @@ -3,9 +3,13 @@ import { MongooseModule } from '@nestjs/mongoose'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { CatModule } from './cat/cat.module'; +import { MongooseModuleConfigService } from './config/mongoose-module-config.service'; @Module({ - imports: [MongooseModule.forRoot('mongodb://localhost:27017'), CatModule], + imports: [ + MongooseModule.forRootAsync({ useClass: MongooseModuleConfigService }), + CatModule, + ], controllers: [AppController], providers: [AppService], }) diff --git a/apps/mongo-sample/src/cat/cat.dto.ts b/apps/mongo-sample/src/cat/cat.dto.ts deleted file mode 100644 index 492fa047..00000000 --- a/apps/mongo-sample/src/cat/cat.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface CatDTO { - _id?: string; - name?: string; - breed?: string; - age?: number; -} diff --git a/apps/mongo-sample/src/cat/cat.module.ts b/apps/mongo-sample/src/cat/cat.module.ts index ad973a8d..34d0047c 100644 --- a/apps/mongo-sample/src/cat/cat.module.ts +++ b/apps/mongo-sample/src/cat/cat.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; -import { CatController } from './cat.controller'; -import { CatService } from './cat.service'; import { MongooseModule } from '@nestjs/mongoose'; -import { CatSchema } from './schemas/cat.schema'; +import { CatController } from './controller/cat.controller'; +import { CatService } from './cat.service'; +import { CatSchema } from './schemas/cat.document'; @Module({ imports: [MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }])], diff --git a/apps/mongo-sample/src/cat/cat.service.spec.ts b/apps/mongo-sample/src/cat/cat.service.spec.ts index 6cd2dbf7..c179fada 100644 --- a/apps/mongo-sample/src/cat/cat.service.spec.ts +++ b/apps/mongo-sample/src/cat/cat.service.spec.ts @@ -9,38 +9,57 @@ * and add your fields on top. Seriously, 59 plus fields is a lot. */ +import { Model, Query } from 'mongoose'; import { Test, TestingModule } from '@nestjs/testing'; -import { CatService } from './cat.service'; +import { createMock } from '@golevelup/nestjs-testing'; import { getModelToken } from '@nestjs/mongoose'; +import { CatService } from './cat.service'; import { Cat } from './interfaces/cat.interface'; -import { createMock } from '@golevelup/nestjs-testing'; -import { Model, Query } from 'mongoose'; -import { CatDoc } from './interfaces/cat-document.interface'; +import { CatDocument } from './schemas/cat.document'; const lasagna = 'lasagna lover'; // I'm lazy and like to have functions that can be re-used to deal with a lot of my initialization/creation logic -const mockCat = ( +const mockCat: ( + name?: string, + id?: string, + age?: number, + breed?: string, +) => Cat = ( name = 'Ventus', id = 'a uuid', age = 4, breed = 'Russian Blue', -): Cat => ({ - name, - id, - age, - breed, -}); +) => { + return { + name, + id, + age, + breed, + }; +}; // still lazy, but this time using an object instead of multiple parameters -const mockCatDoc = (mock?: Partial): Partial => ({ - name: mock?.name || 'Ventus', - _id: mock?.id || 'a uuid', - age: mock?.age || 4, - breed: mock?.breed || 'Russian Blue', -}); +const mockCatDoc: (mock?: { + name?: string; + id?: string; + breed?: string; + age?: number; +}) => Partial = (mock?: { + name: string; + id: string; + age: number; + breed: string; +}) => { + return { + name: (mock && mock.name) || 'Ventus', + _id: (mock && mock.id) || 'a uuid', + age: (mock && mock.age) || 4, + breed: (mock && mock.breed) || 'Russian Blue', + }; +}; -const catArray = [ +const catArray: Cat[] = [ mockCat(), mockCat('Vitani', 'a new uuid', 2, 'Tabby'), mockCat('Simba', 'the king', 14, 'Lion'), @@ -54,7 +73,7 @@ const catDocArray = [ describe('CatService', () => { let service: CatService; - let model: Model; + let model: Model; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -78,7 +97,7 @@ describe('CatService', () => { }).compile(); service = module.get(CatService); - model = module.get>(getModelToken('Cat')); + model = module.get>(getModelToken('Cat')); }); it('should be defined', () => { @@ -97,24 +116,30 @@ describe('CatService', () => { jest.spyOn(model, 'find').mockReturnValue({ exec: jest.fn().mockResolvedValueOnce(catDocArray), } as any); + const cats = await service.getAll(); + expect(cats).toEqual(catArray); }); + it('should getOne by id', async () => { jest.spyOn(model, 'findOne').mockReturnValueOnce( - createMock>({ + createMock>({ exec: jest .fn() .mockResolvedValueOnce(mockCatDoc({ name: 'Ventus', id: 'an id' })), }), ); + const findMockCat = mockCat('Ventus', 'an id'); const foundCat = await service.getOne('an id'); + expect(foundCat).toEqual(findMockCat); }); + it('should getOne by name', async () => { jest.spyOn(model, 'findOne').mockReturnValueOnce( - createMock>({ + createMock>({ exec: jest .fn() .mockResolvedValueOnce( @@ -122,30 +147,36 @@ describe('CatService', () => { ), }), ); + const findMockCat = mockCat('Mufasa', 'the dead king'); const foundCat = await service.getOneByName('Mufasa'); + expect(foundCat).toEqual(findMockCat); }); + it('should insert a new cat', async () => { jest.spyOn(model, 'create').mockImplementationOnce(() => Promise.resolve({ - _id: 'some id', + id: 'some id', name: 'Oliver', age: 1, breed: 'Tabby', }), ); + const newCat = await service.insertOne({ name: 'Oliver', age: 1, breed: 'Tabby', }); + expect(newCat).toEqual(mockCat('Oliver', 'some id', 1, 'Tabby')); }); // jest is complaining about findOneAndUpdate. Can't say why at the moment. + it.skip('should update a cat successfully', async () => { jest.spyOn(model, 'findOneAndUpdate').mockReturnValueOnce( - createMock>({ + createMock>({ exec: jest.fn().mockResolvedValueOnce({ _id: lasagna, name: 'Garfield', @@ -154,22 +185,28 @@ describe('CatService', () => { }), }), ); + const updatedCat = await service.updateOne({ _id: lasagna, name: 'Garfield', breed: 'Tabby', age: 42, }); + expect(updatedCat).toEqual(mockCat('Garfield', lasagna, 42, 'Tabby')); }); + it('should delete a cat successfully', async () => { // really just returning a truthy value here as we aren't doing any logic with the return - jest.spyOn(model, 'remove').mockResolvedValueOnce(true as any); + jest.spyOn(model, 'remove').mockResolvedValueOnce(true); + expect(await service.deleteOne('a bad id')).toEqual({ deleted: true }); }); + it('should not delete a cat', async () => { // really just returning a falsy value here as we aren't doing any logic with the return jest.spyOn(model, 'remove').mockRejectedValueOnce(new Error('Bad delete')); + expect(await service.deleteOne('a bad id')).toEqual({ deleted: false, message: 'Bad delete', diff --git a/apps/mongo-sample/src/cat/cat.service.ts b/apps/mongo-sample/src/cat/cat.service.ts index 8bd36220..b12e78ef 100644 --- a/apps/mongo-sample/src/cat/cat.service.ts +++ b/apps/mongo-sample/src/cat/cat.service.ts @@ -1,42 +1,26 @@ +import { Model } from 'mongoose'; import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; -import { Model } from 'mongoose'; -import { CatDTO } from './cat.dto'; import { Cat } from './interfaces/cat.interface'; -import { CatDoc } from './interfaces/cat-document.interface'; +import { CatDocument } from './schemas/cat.document'; +import { CreateCatDto, UpdateCatDto } from './dto/cat-dto'; @Injectable() export class CatService { - constructor(@InjectModel('Cat') private readonly catModel: Model) {} + constructor( + @InjectModel('Cat') private readonly catModel: Model, + ) {} async getAll(): Promise { - const catDocs = await this.catModel.find().exec(); - return catDocs.map((doc) => ({ - id: doc._id, - age: doc.age, - name: doc.name, - breed: doc.breed, - })); + return this.catModel.find().lean().exec(); } async getOne(id: string): Promise { - const cat = await this.catModel.findOne({ _id: id }).exec(); - return { - id: cat._id, - age: cat.age, - breed: cat.breed, - name: cat.name, - }; + return this.catModel.findOne({ _id: id }).exec(); } async getOneByName(name: string): Promise { - const cat = await this.catModel.findOne({ name }).exec(); - return { - id: cat._id, - age: cat.age, - breed: cat.breed, - name: cat.name, - }; + return this.catModel.findOne({ name }).exec(); } /** @@ -45,30 +29,17 @@ export class CatService { * Instead, you can use the class method `create` to achieve * the same effect. */ - async insertOne(cat: CatDTO): Promise { - const retCat = await this.catModel.create(cat as any); - return { - id: retCat._id, - age: retCat.age, - name: retCat.name, - breed: retCat.breed, - }; + async insertOne(cat: CreateCatDto): Promise { + return this.catModel.create(cat); } - async updateOne(cat: CatDTO): Promise { + async updateOne(cat: UpdateCatDto): Promise { const { _id } = cat; - const foundCat = await this.catModel.findOneAndUpdate({ _id }, cat).exec(); - return { - id: foundCat._id, - age: foundCat.age, - breed: foundCat.breed, - name: foundCat.name, - }; + return this.catModel.findOneAndUpdate({ _id }, cat).exec(); } async deleteOne(id: string): Promise<{ deleted: boolean; message?: string }> { try { - // tslint:disable-next-line: no-invalid-await await this.catModel.remove({ id }); return { deleted: true }; } catch (err) { diff --git a/apps/mongo-sample/src/cat/cat.controller.spec.ts b/apps/mongo-sample/src/cat/controller/cat.controller.spec.ts similarity index 91% rename from apps/mongo-sample/src/cat/cat.controller.spec.ts rename to apps/mongo-sample/src/cat/controller/cat.controller.spec.ts index 065a74aa..38dcc4dd 100644 --- a/apps/mongo-sample/src/cat/cat.controller.spec.ts +++ b/apps/mongo-sample/src/cat/controller/cat.controller.spec.ts @@ -1,9 +1,9 @@ import { createMock } from '@golevelup/nestjs-testing'; import { Test, TestingModule } from '@nestjs/testing'; import { CatController } from './cat.controller'; -import { CatDTO } from './cat.dto'; -import { CatService } from './cat.service'; -import { Cat } from './interfaces/cat.interface'; +import { CreateCatDto, UpdateCatDto } from '../dto/cat-dto'; +import { CatService } from '../cat.service'; +import { Cat } from '../interfaces/cat.interface'; const testCat1 = 'Test Cat 1'; const testBreed1 = 'Test Breed 1'; @@ -43,12 +43,12 @@ describe('Cat Controller', () => { ), insertOne: jest .fn() - .mockImplementation((cat: CatDTO) => + .mockImplementation((cat: CreateCatDto) => Promise.resolve({ _id: 'a uuid', ...cat }), ), updateOne: jest .fn() - .mockImplementation((cat: CatDTO) => + .mockImplementation((cat: CreateCatDto) => Promise.resolve({ _id: 'a uuid', ...cat }), ), deleteOne: jest.fn().mockResolvedValue({ deleted: true }), @@ -86,6 +86,7 @@ describe('Cat Controller', () => { ]); }); }); + describe('getById', () => { it('should get a single cat', () => { expect(controller.getById('a strange id')).resolves.toEqual({ @@ -102,6 +103,7 @@ describe('Cat Controller', () => { }); }); }); + describe('getByName', () => { it('should get a cat back', async () => { expect(controller.getByName('Ventus')).resolves.toEqual({ @@ -109,6 +111,7 @@ describe('Cat Controller', () => { breed: testBreed1, age: 4, }); + // using the really cool @golevelup/nestjs-testing module's utility function here // otherwise we need to pass `as any` or we need to mock all 54+ attributes of Document const aquaMock = createMock({ @@ -116,17 +119,21 @@ describe('Cat Controller', () => { breed: 'Maine Coon', age: 5, }); + const getByNameSpy = jest .spyOn(service, 'getOneByName') .mockResolvedValueOnce(aquaMock); + const getResponse = await controller.getByName('Aqua'); + expect(getResponse).toEqual(aquaMock); expect(getByNameSpy).toBeCalledWith('Aqua'); }); }); + describe('newCat', () => { it('should create a new cat', () => { - const newCatDTO: CatDTO = { + const newCatDTO: CreateCatDto = { name: 'New Cat 1', breed: 'New Breed 1', age: 4, @@ -137,32 +144,36 @@ describe('Cat Controller', () => { }); }); }); + describe('updateCat', () => { it('should update a new cat', () => { - const newCatDTO: CatDTO = { + const updateCatDto: UpdateCatDto = { + _id: 'a uuid', name: 'New Cat 1', breed: 'New Breed 1', age: 4, }; - expect(controller.updateCat(newCatDTO)).resolves.toEqual({ - _id: 'a uuid', - ...newCatDTO, - }); + + expect(controller.updateCat(updateCatDto)).resolves.toEqual(updateCatDto); }); }); + describe('deleteCat', () => { it('should return that it deleted a cat', () => { expect(controller.deleteCat('a uuid that exists')).resolves.toEqual({ deleted: true, }); }); + it('should return that it did not delete a cat', () => { const deleteSpy = jest .spyOn(service, 'deleteOne') .mockResolvedValueOnce({ deleted: false }); + expect( controller.deleteCat('a uuid that does not exist'), ).resolves.toEqual({ deleted: false }); + expect(deleteSpy).toBeCalledWith('a uuid that does not exist'); }); }); diff --git a/apps/mongo-sample/src/cat/cat.controller.ts b/apps/mongo-sample/src/cat/controller/cat.controller.ts similarity index 75% rename from apps/mongo-sample/src/cat/cat.controller.ts rename to apps/mongo-sample/src/cat/controller/cat.controller.ts index f65c57b5..978bb24d 100644 --- a/apps/mongo-sample/src/cat/cat.controller.ts +++ b/apps/mongo-sample/src/cat/controller/cat.controller.ts @@ -8,9 +8,9 @@ import { Post, Query, } from '@nestjs/common'; -import { CatDTO } from './cat.dto'; -import { Cat } from './interfaces/cat.interface'; -import { CatService } from './cat.service'; +import { CreateCatDto, UpdateCatDto } from '../dto/cat-dto'; +import { Cat } from '../interfaces/cat.interface'; +import { CatService } from '../cat.service'; @Controller('cat') export class CatController { @@ -32,12 +32,12 @@ export class CatController { } @Post('/new') - async newCat(@Body() cat: CatDTO): Promise { + async newCat(@Body() cat: CreateCatDto): Promise { return this.catService.insertOne(cat); } @Patch('/update') - async updateCat(@Body() cat: CatDTO): Promise { + async updateCat(@Body() cat: UpdateCatDto): Promise { return this.catService.updateOne(cat); } diff --git a/apps/mongo-sample/src/cat/dto/cat-dto.ts b/apps/mongo-sample/src/cat/dto/cat-dto.ts new file mode 100644 index 00000000..a440bbd6 --- /dev/null +++ b/apps/mongo-sample/src/cat/dto/cat-dto.ts @@ -0,0 +1,5 @@ +import { Cat } from '../interfaces/cat.interface'; + +export type CreateCatDto = Readonly; + +export type UpdateCatDto = CreateCatDto & Readonly<{ _id: string }>; diff --git a/apps/mongo-sample/src/cat/interfaces/cat-document.interface.ts b/apps/mongo-sample/src/cat/interfaces/cat-document.interface.ts deleted file mode 100644 index 51da464e..00000000 --- a/apps/mongo-sample/src/cat/interfaces/cat-document.interface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Document } from 'mongoose'; - -export interface CatDoc extends Document { - age: number; - name: string; - breed: string; -} diff --git a/apps/mongo-sample/src/cat/interfaces/cat.interface.ts b/apps/mongo-sample/src/cat/interfaces/cat.interface.ts index 0d22dc8f..6d158582 100644 --- a/apps/mongo-sample/src/cat/interfaces/cat.interface.ts +++ b/apps/mongo-sample/src/cat/interfaces/cat.interface.ts @@ -2,5 +2,4 @@ export interface Cat { age: number; name: string; breed: string; - id: string; } diff --git a/apps/mongo-sample/src/cat/schemas/cat.document.ts b/apps/mongo-sample/src/cat/schemas/cat.document.ts new file mode 100644 index 00000000..92b5bf73 --- /dev/null +++ b/apps/mongo-sample/src/cat/schemas/cat.document.ts @@ -0,0 +1,17 @@ +import { Document } from 'mongoose'; +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Cat } from '../interfaces/cat.interface'; + +@Schema({ versionKey: false }) +export class CatDocument extends Document implements Cat { + @Prop() + age: number; + + @Prop() + name: string; + + @Prop() + breed: string; +} + +export const CatSchema = SchemaFactory.createForClass(CatDocument); diff --git a/apps/mongo-sample/src/cat/schemas/cat.schema.ts b/apps/mongo-sample/src/cat/schemas/cat.schema.ts deleted file mode 100644 index 02ecd8ec..00000000 --- a/apps/mongo-sample/src/cat/schemas/cat.schema.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Schema } from 'mongoose'; - -export const CatSchema = new Schema({ - name: String, - age: Number, - breed: String, -}); diff --git a/apps/mongo-sample/src/config/mongoose-module-config.service.ts b/apps/mongo-sample/src/config/mongoose-module-config.service.ts new file mode 100644 index 00000000..77d03ad7 --- /dev/null +++ b/apps/mongo-sample/src/config/mongoose-module-config.service.ts @@ -0,0 +1,12 @@ +import { + MongooseModuleOptions, + MongooseOptionsFactory, +} from '@nestjs/mongoose'; + +export class MongooseModuleConfigService implements MongooseOptionsFactory { + createMongooseOptions(): MongooseModuleOptions { + return { + uri: 'mongodb://localhost:27017', + }; + } +} diff --git a/apps/mongo-sample/test/cat.e2e-spec.ts b/apps/mongo-sample/test/cat.e2e-spec.ts new file mode 100644 index 00000000..3fa9087d --- /dev/null +++ b/apps/mongo-sample/test/cat.e2e-spec.ts @@ -0,0 +1,53 @@ +import * as request from 'supertest'; +import { Response } from 'supertest'; +import { Model } from 'mongoose'; +import { MockFactory } from 'mockingbird-ts'; +import { Test, TestingModule } from '@nestjs/testing'; +import { HttpStatus, INestApplication } from '@nestjs/common'; +import { MongoInMemoryConfigService } from './common/mongo-in-memory-config.service'; +import { AppModule } from '../src/app.module'; +import { MongooseModuleConfigService } from '../src/config/mongoose-module-config.service'; +import { CatMock } from './common/cat.mock'; +import { getModelToken } from '@nestjs/mongoose'; +import { CatDocument } from '../src/cat/schemas/cat.document'; + +describe('Cats Application (e2e)', () => { + let app: INestApplication; + let model: Model; + let cats; + + beforeAll(async () => { + cats = MockFactory.create(CatMock, { count: 3 }); + + const moduleRef: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }) + .overrideProvider(MongooseModuleConfigService) + // Use in-memory database instead of the real one + .useClass(MongoInMemoryConfigService) + .compile(); + + app = moduleRef.createNestApplication(); + + // Get the mongoose model for 'Cat' + model = moduleRef.get(getModelToken('Cat')); + + // 'Seed' the cats fixture in the database + await model.create(cats); + + await app.init(); + }); + + afterAll(async () => { + await app.close(); + }); + + it('/cat (GET)', async () => { + const response: Response = await request(app.getHttpServer()).get('/cat'); + + expect(response.status).toBe(HttpStatus.OK); + expect(response.body).toEqual( + cats.map((cat) => ({ ...cat, _id: expect.any(String) })), + ); + }); +}); diff --git a/apps/mongo-sample/test/common/cat.mock.ts b/apps/mongo-sample/test/common/cat.mock.ts new file mode 100644 index 00000000..0db7be59 --- /dev/null +++ b/apps/mongo-sample/test/common/cat.mock.ts @@ -0,0 +1,13 @@ +import { Mock } from 'mockingbird-ts'; +import { Cat } from '../../src/cat/interfaces/cat.interface'; + +export class CatMock implements Cat { + @Mock((faker) => faker.name.firstName()) + name: string; + + @Mock((faker) => faker.random.number(15)) + age: number; + + @Mock() + breed: string; +} diff --git a/apps/mongo-sample/test/common/mongo-in-memory-config.service.ts b/apps/mongo-sample/test/common/mongo-in-memory-config.service.ts new file mode 100644 index 00000000..9977b2af --- /dev/null +++ b/apps/mongo-sample/test/common/mongo-in-memory-config.service.ts @@ -0,0 +1,49 @@ +import { + MongooseModuleOptions, + MongooseOptionsFactory, +} from '@nestjs/mongoose'; +import { MongoMemoryServer } from 'mongodb-memory-server'; +import { Connection } from 'mongoose'; + +export class MongoInMemoryConfigService implements MongooseOptionsFactory { + async createMongooseOptions(): Promise { + const mongod = new MongoMemoryServer({ autoStart: true }); + const uri = await mongod.getUri(); + + await mongod.start(); + + return { + uri, + connectionFactory: (connection: Connection) => { + connection.on('error', (error: any) => { + console.error(`MongoInMemory connection error: ${error.reason}`); + throw error; + }); + + connection.on('open', () => + console.log(`MongoInMemory connection opened`), + ); + + connection.on('connected', () => { + console.log('MongoInMemory connection established successfully'); + console.debug(`Connection URI @ ${uri}`); + }); + + connection.on('disconnected', () => + console.warn('MongoInMemory connection disconnected'), + ); + + process.on('exit', async () => { + console.log( + 'MongoInMemory connection disconnected through app termination', + ); + + await connection.close(); + await mongod.stop(); + }); + + return connection; + }, + }; + } +} diff --git a/package-lock.json b/package-lock.json index e6d1bfe5..5a2cbe2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -214,9 +214,9 @@ } }, "graphql-tag": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.0.tgz", - "integrity": "sha512-iK040pFYpQpHfqF5UJOlYu2XEw6wx56aiyKJP1zqhxabGssqfbTIqz6U++cBwx/Izad0JNq6IsWvrL+p6d1GOA==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.1.tgz", + "integrity": "sha512-LPewEE1vzGkHnCO8zdOGogKsHHBdtpGyihow1UuMwp6RnZa0lAS7NcbvltLOuo4pi5diQCPASAXZkQq44ffixA==", "requires": { "tslib": "^1.14.1" }, @@ -459,12 +459,12 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.13.tgz", - "integrity": "sha512-Vs/e9wv7rakKYeywsmEBSRC9KtmE7Px+YBlESekLeJOF0zbGUicGfXSNi3o+tfXSNS48U/7K9mIOOCR79Cl3+Q==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz", + "integrity": "sha512-KbSEj8l9zYkMVHpQqM3wJNxS1d9h3U9vm/uE5tpjMbaj3lTp+0noe3KPsV5dSD9jxKnf9jO9Ip9FX5PKNZCKow==", "requires": { "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.12.16", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-replace-supers": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13" @@ -507,9 +507,9 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "requires": { "@babel/types": "^7.12.13" } @@ -557,9 +557,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==" + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==" }, "@babel/template": { "version": "7.12.13", @@ -1062,9 +1062,9 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "requires": { "@babel/types": "^7.12.13" } @@ -1117,9 +1117,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==" + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==" }, "@babel/template": { "version": "7.12.13", @@ -1286,9 +1286,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==" + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==" }, "@babel/template": { "version": "7.12.13", @@ -1395,9 +1395,9 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "requires": { "@babel/types": "^7.12.13" } @@ -1482,9 +1482,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==" + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==" }, "@babel/template": { "version": "7.12.13", @@ -1580,9 +1580,9 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "requires": { "@babel/types": "^7.12.13" } @@ -1635,9 +1635,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==" + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==" }, "@babel/template": { "version": "7.12.13", @@ -1733,9 +1733,9 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.13.tgz", - "integrity": "sha512-hhXZMYR8t9RvduN2uW4sjl6MRtUhzNE726JvoJhpjhxKgRUVkZqTsA0xc49ALZxQM7H26pZ/lLvB2Yrea9dllA==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.16.tgz", + "integrity": "sha512-dNu0vAbIk8OkqJfGtYF6ADk6jagoyAl+Ks5aoltbAlfoKv8d6yooi3j+kObeSQaCj9PgN6KMZPB90wWyek5TmQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", "@babel/helper-module-imports": "^7.12.13", @@ -5444,6 +5444,17 @@ } } }, + "@plumier/reflect": { + "version": "1.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@plumier/reflect/-/reflect-1.0.0-rc.6.tgz", + "integrity": "sha512-7AE45Cx2eoLXD0s31ra6GGRgJsHlrdpI70wnqeMay2x7D1OMlSujasTk2LA4NPTZyhPgtpexYLW2DqXqLJGnaw==", + "dev": true, + "requires": { + "@types/acorn": "4.0.5", + "acorn": "8.0.4", + "reflect-metadata": "^0.1.13" + } + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -5591,6 +5602,15 @@ "@types/node": "*" } }, + "@types/acorn": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.5.tgz", + "integrity": "sha512-603sPiZ4GVRHPvn6vNgEAvJewKsy+zwRWYS2MeIMemgoAtcjlw2G3lALxrb9OPA17J28bkB71R33yXlQbUatCA==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -5769,6 +5789,12 @@ "@types/range-parser": "*" } }, + "@types/faker": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.6.tgz", + "integrity": "sha512-D+gfFWR/YCvlrYL8lgNZO1jKgIUW+cfhxsgMOqUMYwCI+tl0htD7vCCXp/oJsIxJpxuI7zqmo3gpVQBkFCM4iA==", + "dev": true + }, "@types/fs-capacitor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", @@ -6050,6 +6076,12 @@ "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", "dev": true }, + "@types/tmp": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.0.tgz", + "integrity": "sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ==", + "dev": true + }, "@types/uglify-js": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz", @@ -6153,32 +6185,6 @@ "tsutils": "^3.17.1" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz", - "integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/visitor-keys": "4.15.0" - } - }, - "@typescript-eslint/types": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz", - "integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz", - "integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "eslint-visitor-keys": "^2.0.0" - } - }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -6202,58 +6208,6 @@ "@typescript-eslint/typescript-estree": "4.15.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz", - "integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/visitor-keys": "4.15.0" - } - }, - "@typescript-eslint/types": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz", - "integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz", - "integrity": "sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/visitor-keys": "4.15.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz", - "integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/parser": { @@ -6620,7 +6574,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "optional": true, "requires": { "debug": "4" } @@ -7833,6 +7786,12 @@ "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -8560,6 +8519,12 @@ } } }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -10045,6 +10010,12 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "faker": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.4.0.tgz", + "integrity": "sha512-Y9n/Ky/xZx/Bj8DePvXspUYRtHl/rGQytoIT5LaxmNwSe3wWyOeOXb3lT6Dpipq240PVpeFaGKzScz/5fvff2g==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", @@ -10121,6 +10092,15 @@ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figlet": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", @@ -10176,6 +10156,17 @@ } } }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, "find-node-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.0.0.tgz", @@ -10186,6 +10177,12 @@ "merge": "^1.2.1" } }, + "find-package-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", + "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==", + "dev": true + }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -10541,6 +10538,12 @@ "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==" }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -10630,6 +10633,12 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, "get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", @@ -11171,7 +11180,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "optional": true, "requires": { "agent-base": "6", "debug": "4" @@ -14582,6 +14590,15 @@ "p-locate": "^4.1.0" } }, + "lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "dev": true, + "requires": { + "signal-exit": "^3.0.2" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -14777,6 +14794,23 @@ "sourcemap-codec": "^1.4.4" } }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -14836,6 +14870,12 @@ "object-visit": "^1.0.0" } }, + "md5-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -15084,6 +15124,16 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, + "mockingbird-ts": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/mockingbird-ts/-/mockingbird-ts-1.0.0-beta.1.tgz", + "integrity": "sha512-YxZoFClnaY+aa4AZq4oL/D//C/NqKjqedWXMnviuvLDnPVolrM7RE62U18mx+xlkVQ3gkkwwp8znqj5qygIQTw==", + "dev": true, + "requires": { + "@plumier/reflect": "^1.0.0-rc.5", + "reflect-metadata": "^0.1.13" + } + }, "moment": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz", @@ -15110,6 +15160,122 @@ "saslprep": "^1.0.0" } }, + "mongodb-memory-server": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-6.9.3.tgz", + "integrity": "sha512-VU2ey+fknmZflHltPCznZr9fja8T6K7DTG5m7wSxmQC/Qf/kkKmRGqIPcZoEU5znRR/8m/EaOe+hFWkjmh1W5A==", + "dev": true, + "requires": { + "mongodb-memory-server-core": "6.9.3" + } + }, + "mongodb-memory-server-core": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-6.9.3.tgz", + "integrity": "sha512-9ZaWemIQLbu9VG553ksMiV7TNnzICqXhSSQv/7Io6dnuO8VpoLLdd1wIz+r2YuWFP7U159JPWQc8QG9jIL27og==", + "dev": true, + "requires": { + "@types/tmp": "^0.2.0", + "camelcase": "^6.0.0", + "cross-spawn": "^7.0.3", + "debug": "^4.2.0", + "find-cache-dir": "^3.3.1", + "find-package-json": "^1.2.0", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.0", + "lockfile": "^1.0.4", + "md5-file": "^5.0.0", + "mkdirp": "^1.0.4", + "mongodb": "3.6.2", + "semver": "^7.3.2", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "uuid": "8.3.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "mongodb": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz", + "integrity": "sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA==", + "dev": true, + "optional": true, + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "mongoose": { "version": "5.11.15", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.15.tgz", @@ -15972,6 +16138,12 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -18187,6 +18359,43 @@ "yallist": "^4.0.0" } }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -18625,9 +18834,9 @@ "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" }, "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", + "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -18824,9 +19033,9 @@ "integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==" }, "ua-parser-js": { - "version": "0.7.23", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz", - "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==" + "version": "0.7.24", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.24.tgz", + "integrity": "sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw==" }, "uglify-js": { "version": "3.9.3", @@ -19571,6 +19780,16 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/package.json b/package.json index 7f99bef1..436a21d4 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@nestjs/schematics": "^7.2.7", "@nestjs/testing": "^7.6.12", "@types/express": "^4.17.11", + "@types/faker": "^5.1.6", "@types/jest": "^26.0.20", "@types/node": "^14.14.27", "@types/redis": "^2.8.28", @@ -92,9 +93,12 @@ "eslint": "^7.19.0", "eslint-config-prettier": "^7.2.0", "eslint-plugin-prettier": "^3.3.1", + "faker": "^5.4.0", "husky": "^5.0.9", "jest": "^26.6.3", "lint-staged": "^10.5.4", + "mockingbird-ts": "^1.0.0-beta.1", + "mongodb-memory-server": "^6.9.3", "prettier": "^2.2.1", "supertest": "^6.1.3", "ts-jest": "^26.5.1",