mirror of
https://github.com/nestjs/nest.git
synced 2026-02-24 00:02:56 +00:00
Compare commits
72 Commits
H4ad-perf/
...
v9.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eba8f15683 | ||
|
|
2310c56f4c | ||
|
|
06ea451f1f | ||
|
|
b2c55a6f79 | ||
|
|
3d366ce5c5 | ||
|
|
f7e366600f | ||
|
|
55bc840edb | ||
|
|
22c3175552 | ||
|
|
c1815d2f8c | ||
|
|
34654244a7 | ||
|
|
2924c03aa3 | ||
|
|
d1ec9db5f2 | ||
|
|
cb7e10dbc3 | ||
|
|
511e7162a6 | ||
|
|
32b0d9c600 | ||
|
|
967a136834 | ||
|
|
1aadd30f46 | ||
|
|
ae76b521d6 | ||
|
|
38c365215a | ||
|
|
80b8c86c68 | ||
|
|
8756ed3d68 | ||
|
|
d616861698 | ||
|
|
c64312fded | ||
|
|
304e6bf5bb | ||
|
|
161198379a | ||
|
|
661104d981 | ||
|
|
f71554ca96 | ||
|
|
a986e7e907 | ||
|
|
920f430d4d | ||
|
|
cd0462fbcb | ||
|
|
b9910a400a | ||
|
|
6d88e3cd3c | ||
|
|
fbf1ab7a81 | ||
|
|
868bbcd8b9 | ||
|
|
4e783852b3 | ||
|
|
07a84ae224 | ||
|
|
7bc72671b6 | ||
|
|
a560c3466a | ||
|
|
f10c917b71 | ||
|
|
208d8ca184 | ||
|
|
32aeb7a8a3 | ||
|
|
a185e63281 | ||
|
|
0b395d1f59 | ||
|
|
f396dc1ddf | ||
|
|
aafdac62a0 | ||
|
|
e8944675cb | ||
|
|
4d4f3f82de | ||
|
|
994f8c4e42 | ||
|
|
58ee3bf2f3 | ||
|
|
5deabef549 | ||
|
|
9a47a6ce70 | ||
|
|
eee8968d82 | ||
|
|
35357053b1 | ||
|
|
ceea86d6ed | ||
|
|
452f19461c | ||
|
|
7792c43b93 | ||
|
|
363ab79b5f | ||
|
|
9efb84fc22 | ||
|
|
1b90339d8b | ||
|
|
a25bfa86ed | ||
|
|
d5e1cd18fc | ||
|
|
9b073748cb | ||
|
|
0444f9c89e | ||
|
|
1b9bb76d07 | ||
|
|
c817014c7d | ||
|
|
accb1dc014 | ||
|
|
1755537a77 | ||
|
|
7b81d0571d | ||
|
|
7afed825be | ||
|
|
d6097a10ac | ||
|
|
584015bc77 | ||
|
|
f3e6c54b3e |
@@ -1 +1,3 @@
|
||||
**/node_modules/**
|
||||
**/node_modules/**
|
||||
*.d.ts
|
||||
*.js
|
||||
@@ -15,7 +15,7 @@ scalar Date
|
||||
|
||||
type Query {
|
||||
recipe(id: String!): Recipe!
|
||||
recipes(skip: Int = 0, take: Int = 25): [Recipe!]!
|
||||
recipes(skip: Int! = 0, take: Int! = 25): [Recipe!]!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { OptionsUrlencoded } from 'body-parser';
|
||||
import { expect } from 'chai';
|
||||
import * as request from 'supertest';
|
||||
import { AppModule } from '../src/app.module';
|
||||
|
||||
describe('Body Parser (Express Application)', () => {
|
||||
const moduleFixture = Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
});
|
||||
let app: NestExpressApplication;
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe('application/json', () => {
|
||||
const stringLimit = '{ "msg": "Hello, World" }';
|
||||
const stringOverLimit = '{ "msg": "Hello, World!" }';
|
||||
|
||||
beforeEach(async () => {
|
||||
const testFixture = await moduleFixture.compile();
|
||||
|
||||
app = testFixture
|
||||
.createNestApplication<NestExpressApplication>({
|
||||
rawBody: true,
|
||||
logger: false,
|
||||
})
|
||||
.useBodyParser('json', { limit: Buffer.from(stringLimit).byteLength });
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('should allow request with matching body limit', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/')
|
||||
.set('Content-Type', 'application/json')
|
||||
.send(stringLimit)
|
||||
.expect(201);
|
||||
|
||||
expect(response.body).to.eql({
|
||||
raw: stringLimit,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if post body is larger than limit', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.post('/')
|
||||
.set('Content-Type', 'application/json')
|
||||
.send(stringOverLimit)
|
||||
.expect(413);
|
||||
});
|
||||
});
|
||||
|
||||
describe('application/x-www-form-urlencoded', () => {
|
||||
const stringLimit = 'msg=Hello, World';
|
||||
const stringOverLimit = 'msg=Hello, World!';
|
||||
|
||||
beforeEach(async () => {
|
||||
const testFixture = await moduleFixture.compile();
|
||||
|
||||
app = testFixture
|
||||
.createNestApplication<NestExpressApplication>({
|
||||
rawBody: true,
|
||||
logger: false,
|
||||
})
|
||||
.useBodyParser<OptionsUrlencoded>('urlencoded', {
|
||||
limit: Buffer.from(stringLimit).byteLength,
|
||||
extended: true,
|
||||
});
|
||||
|
||||
await app.init();
|
||||
});
|
||||
it('should allow request with matching body limit', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/')
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
.send(stringLimit)
|
||||
.expect(201);
|
||||
|
||||
expect(response.body).to.eql({
|
||||
raw: stringLimit,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if post body is larger than limit', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.post('/')
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
.send(stringOverLimit)
|
||||
.expect(413);
|
||||
});
|
||||
});
|
||||
});
|
||||
106
integration/nest-application/use-body-parser/e2e/fastify.spec.ts
Normal file
106
integration/nest-application/use-body-parser/e2e/fastify.spec.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import {
|
||||
FastifyAdapter,
|
||||
NestFastifyApplication,
|
||||
} from '@nestjs/platform-fastify';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { expect } from 'chai';
|
||||
import { AppModule } from '../src/app.module';
|
||||
|
||||
describe('Body Parser (Fastify Application)', () => {
|
||||
const moduleFixture = Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
});
|
||||
let app: NestFastifyApplication;
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe('application/json', () => {
|
||||
const stringLimit = '{ "msg": "Hello, World" }';
|
||||
const stringOverLimit = '{ "msg": "Hello, World!" }';
|
||||
|
||||
beforeEach(async () => {
|
||||
const testFixture = await moduleFixture.compile();
|
||||
|
||||
app = testFixture
|
||||
.createNestApplication<NestFastifyApplication>(new FastifyAdapter(), {
|
||||
rawBody: true,
|
||||
logger: false,
|
||||
})
|
||||
.useBodyParser('application/json', {
|
||||
bodyLimit: Buffer.from(stringLimit).byteLength,
|
||||
});
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('should allow request with matching body limit', async () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
payload: stringLimit,
|
||||
});
|
||||
|
||||
expect(JSON.parse(response.body)).to.eql({
|
||||
raw: stringLimit,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if post body is larger than limit', async () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
payload: stringOverLimit,
|
||||
});
|
||||
|
||||
expect(response.statusCode).to.equal(413);
|
||||
});
|
||||
});
|
||||
|
||||
describe('application/x-www-form-urlencoded', () => {
|
||||
const stringLimit = 'msg=Hello, World';
|
||||
const stringOverLimit = 'msg=Hello, World!';
|
||||
|
||||
beforeEach(async () => {
|
||||
const testFixture = await moduleFixture.compile();
|
||||
|
||||
app = testFixture
|
||||
.createNestApplication<NestFastifyApplication>(new FastifyAdapter(), {
|
||||
rawBody: true,
|
||||
logger: false,
|
||||
})
|
||||
.useBodyParser('application/x-www-form-urlencoded', {
|
||||
bodyLimit: Buffer.from(stringLimit).byteLength,
|
||||
});
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('should allow request with matching body limit', async () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
||||
payload: stringLimit,
|
||||
});
|
||||
|
||||
expect(JSON.parse(response.body)).to.eql({
|
||||
raw: stringLimit,
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if post body is larger than limit', async () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
||||
payload: stringOverLimit,
|
||||
});
|
||||
|
||||
expect(response.statusCode).to.equal(413);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Controller, Post, Req, RawBodyRequest } from '@nestjs/common';
|
||||
import { IncomingMessage } from 'http';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
@Post()
|
||||
index(@Req() req: RawBodyRequest<IncomingMessage>) {
|
||||
return {
|
||||
raw: req.rawBody?.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [AppController],
|
||||
})
|
||||
export class AppModule {}
|
||||
23
integration/nest-application/use-body-parser/tsconfig.json
Normal file
23
integration/nest-application/use-body-parser/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"lib": ["dom"],
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -3,5 +3,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "9.3.0-beta.3"
|
||||
"version": "9.3.0"
|
||||
}
|
||||
|
||||
@@ -47,15 +47,17 @@ export interface CacheStoreSetOptions<T> {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export interface CacheStoreFactory {
|
||||
/**
|
||||
* Return a configured cache store.
|
||||
*
|
||||
* @param args Cache manager options received from `CacheModule.register()`
|
||||
* or `CacheModule.registerAsync()`
|
||||
*/
|
||||
create(args: LiteralObject): CacheStore;
|
||||
}
|
||||
export type CacheStoreFactory =
|
||||
| {
|
||||
/**
|
||||
* Return a configured cache store.
|
||||
*
|
||||
* @param args Cache manager options received from `CacheModule.register()`
|
||||
* or `CacheModule.registerAsync()`
|
||||
*/
|
||||
create(args: LiteralObject): CacheStore;
|
||||
}
|
||||
| ((args: LiteralObject) => CacheStore | Promise<CacheStore>);
|
||||
|
||||
/**
|
||||
* Interface defining Cache Manager configuration options.
|
||||
|
||||
@@ -101,7 +101,7 @@ export class HttpException extends Error {
|
||||
} else if (this.constructor) {
|
||||
this.message = this.constructor.name
|
||||
.match(/[A-Z][a-z]+|[0-9]+/g)
|
||||
.join(' ');
|
||||
?.join(' ') ?? 'Error';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface HttpServer<TRequest = any, TResponse = any> {
|
||||
| RequestHandler<TRequest, TResponse>
|
||||
| ErrorHandler<TRequest, TResponse>,
|
||||
): any;
|
||||
useBodyParser?(...args: any[]): any;
|
||||
get(handler: RequestHandler<TRequest, TResponse>): any;
|
||||
get(path: string, handler: RequestHandler<TRequest, TResponse>): any;
|
||||
post(handler: RequestHandler<TRequest, TResponse>): any;
|
||||
|
||||
@@ -205,7 +205,7 @@ export class ConfigurableModuleBuilder<
|
||||
static [self.staticMethodKey](
|
||||
options: ModuleOptions & ExtraModuleDefinitionOptions,
|
||||
): DynamicModule {
|
||||
const providers = [
|
||||
const providers: Array<Provider> = [
|
||||
{
|
||||
provide: self.options.optionsInjectionToken,
|
||||
useValue: this.omitExtras(options, self.extras),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/common",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@common)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"homepage": "https://nestjs.com",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { isUndefined } from '../../utils/shared.utils';
|
||||
import { Injectable, Optional } from '../../decorators/core';
|
||||
import { HttpStatus } from '../../enums';
|
||||
import { PipeTransform } from '../../interfaces/features/pipe-transform.interface';
|
||||
import { HttpErrorByCode } from '../../utils/http-error-by-code.util';
|
||||
import { FileValidator } from './file-validator.interface';
|
||||
import { ParseFileOptions } from './parse-file-options.interface';
|
||||
import { isEmpty, isObject } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Defines the built-in ParseFile Pipe. This pipe can be used to validate incoming files
|
||||
@@ -39,20 +39,36 @@ export class ParseFilePipe implements PipeTransform<any> {
|
||||
}
|
||||
|
||||
async transform(value: any): Promise<any> {
|
||||
if (isUndefined(value)) {
|
||||
if (this.thereAreNoFilesIn(value)) {
|
||||
if (this.fileIsRequired) {
|
||||
throw this.exceptionFactory('File is required');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
if (this.validators.length) {
|
||||
await this.validate(value);
|
||||
if (Array.isArray(value)) {
|
||||
await this.validateFiles(value);
|
||||
} else {
|
||||
await this.validate(value);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private validateFiles(files: any[]): Promise<any[]> {
|
||||
return Promise.all(files.map(f => this.validate(f)));
|
||||
}
|
||||
|
||||
private thereAreNoFilesIn(value: any): boolean {
|
||||
if (Array.isArray(value)) {
|
||||
return value.length === 0;
|
||||
} else {
|
||||
return isEmpty(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected async validate(file: any): Promise<any> {
|
||||
for (const validator of this.validators) {
|
||||
await this.validateOrThrow(file, validator);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '../decorators/core/injectable.decorator';
|
||||
import { Optional } from '../decorators/core/optional.decorator';
|
||||
import { Injectable, Optional } from '../decorators/core';
|
||||
import { isObject } from '../utils/shared.utils';
|
||||
import { ConsoleLogger } from './console-logger.service';
|
||||
import { isLogLevelEnabled } from './utils';
|
||||
@@ -126,7 +125,9 @@ export class Logger implements LoggerService {
|
||||
@Logger.WrapBuffer
|
||||
error(message: any, ...optionalParams: any[]) {
|
||||
optionalParams = this.context
|
||||
? optionalParams.concat(this.context)
|
||||
? (optionalParams.length ? optionalParams : [undefined]).concat(
|
||||
this.context,
|
||||
)
|
||||
: optionalParams;
|
||||
|
||||
this.localInstance?.error(message, ...optionalParams);
|
||||
|
||||
@@ -480,43 +480,87 @@ describe('Logger', () => {
|
||||
warn(message: any, context?: string) {}
|
||||
}
|
||||
|
||||
const customLogger = new CustomLogger();
|
||||
const originalLogger = new Logger();
|
||||
describe('with global context', () => {
|
||||
const customLogger = new CustomLogger();
|
||||
const globalContext = 'RandomContext';
|
||||
const originalLogger = new Logger(globalContext);
|
||||
|
||||
let previousLoggerRef: LoggerService;
|
||||
let previousLoggerRef: LoggerService;
|
||||
|
||||
beforeEach(() => {
|
||||
previousLoggerRef =
|
||||
Logger['localInstanceRef'] || Logger['staticInstanceRef'];
|
||||
Logger.overrideLogger(customLogger);
|
||||
beforeEach(() => {
|
||||
previousLoggerRef =
|
||||
Logger['localInstanceRef'] || Logger['staticInstanceRef'];
|
||||
Logger.overrideLogger(customLogger);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Logger.overrideLogger(previousLoggerRef);
|
||||
});
|
||||
|
||||
it('should call custom logger "#log()" method with context as second argument', () => {
|
||||
const message = 'random log message with global context';
|
||||
|
||||
const customLoggerLogSpy = sinon.spy(customLogger, 'log');
|
||||
|
||||
originalLogger.log(message);
|
||||
|
||||
expect(customLoggerLogSpy.called).to.be.true;
|
||||
expect(customLoggerLogSpy.calledWith(message, globalContext)).to.be
|
||||
.true;
|
||||
});
|
||||
it('should call custom logger "#error()" method with context as third argument', () => {
|
||||
const message = 'random error message with global context';
|
||||
|
||||
const customLoggerErrorSpy = sinon.spy(customLogger, 'error');
|
||||
|
||||
originalLogger.error(message);
|
||||
|
||||
expect(customLoggerErrorSpy.called).to.be.true;
|
||||
expect(
|
||||
customLoggerErrorSpy.calledWith(message, undefined, globalContext),
|
||||
).to.be.true;
|
||||
});
|
||||
});
|
||||
describe('without global context', () => {
|
||||
const customLogger = new CustomLogger();
|
||||
const originalLogger = new Logger();
|
||||
|
||||
afterEach(() => {
|
||||
Logger.overrideLogger(previousLoggerRef);
|
||||
});
|
||||
let previousLoggerRef: LoggerService;
|
||||
|
||||
it('should call custom logger "#log()" method', () => {
|
||||
const message = 'random message';
|
||||
const context = 'RandomContext';
|
||||
beforeEach(() => {
|
||||
previousLoggerRef =
|
||||
Logger['localInstanceRef'] || Logger['staticInstanceRef'];
|
||||
Logger.overrideLogger(customLogger);
|
||||
});
|
||||
|
||||
const customLoggerLogSpy = sinon.spy(customLogger, 'log');
|
||||
afterEach(() => {
|
||||
Logger.overrideLogger(previousLoggerRef);
|
||||
});
|
||||
|
||||
originalLogger.log(message, context);
|
||||
it('should call custom logger "#log()" method', () => {
|
||||
const message = 'random message';
|
||||
const context = 'RandomContext';
|
||||
|
||||
expect(customLoggerLogSpy.called).to.be.true;
|
||||
expect(customLoggerLogSpy.calledWith(message, context)).to.be.true;
|
||||
});
|
||||
const customLoggerLogSpy = sinon.spy(customLogger, 'log');
|
||||
|
||||
it('should call custom logger "#error()" method', () => {
|
||||
const message = 'random message';
|
||||
const context = 'RandomContext';
|
||||
originalLogger.log(message, context);
|
||||
|
||||
const customLoggerErrorSpy = sinon.spy(customLogger, 'error');
|
||||
expect(customLoggerLogSpy.called).to.be.true;
|
||||
expect(customLoggerLogSpy.calledWith(message, context)).to.be.true;
|
||||
});
|
||||
|
||||
originalLogger.error(message, context);
|
||||
it('should call custom logger "#error()" method', () => {
|
||||
const message = 'random message';
|
||||
const context = 'RandomContext';
|
||||
|
||||
expect(customLoggerErrorSpy.called).to.be.true;
|
||||
expect(customLoggerErrorSpy.calledWith(message, context)).to.be.true;
|
||||
const customLoggerErrorSpy = sinon.spy(customLogger, 'error');
|
||||
|
||||
originalLogger.error(message, undefined, context);
|
||||
|
||||
expect(customLoggerErrorSpy.called).to.be.true;
|
||||
expect(customLoggerErrorSpy.calledWith(message, undefined, context))
|
||||
.to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,16 +9,16 @@ import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import { lastValueFrom, isObservable } from 'rxjs';
|
||||
import { ExternalExceptionFilterContext } from '../exceptions/external-exception-filter-context';
|
||||
import { FORBIDDEN_MESSAGE } from '../guards/constants';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { GuardsConsumer, GuardsContextCreator } from '../guards';
|
||||
import { STATIC_CONTEXT } from '../injector/constants';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { ContextId } from '../injector/instance-wrapper';
|
||||
import { ModulesContainer } from '../injector/modules-container';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { PipesConsumer } from '../pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '../pipes/pipes-context-creator';
|
||||
import {
|
||||
InterceptorsConsumer,
|
||||
InterceptorsContextCreator,
|
||||
} from '../interceptors';
|
||||
import { PipesConsumer, PipesContextCreator } from '../pipes';
|
||||
import { ContextUtils, ParamProperties } from './context-utils';
|
||||
import { ExternalErrorProxy } from './external-proxy';
|
||||
import { HandlerMetadataStorage } from './handler-metadata-storage';
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
isUndefined,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import { iterate } from 'iterare';
|
||||
import { DeterministicUuidRegistry } from '../inspector/deterministic-uuid-registry';
|
||||
import { UuidFactory } from '../inspector/uuid-factory';
|
||||
import { STATIC_CONTEXT } from './constants';
|
||||
import {
|
||||
isClassProvider,
|
||||
@@ -469,6 +469,6 @@ export class InstanceWrapper<T = any> {
|
||||
let key = this.name?.toString() ?? this.token?.toString();
|
||||
key += this.host?.name ?? '';
|
||||
|
||||
return key ? DeterministicUuidRegistry.get(key) : randomStringGenerator();
|
||||
return key ? UuidFactory.get(key) : randomStringGenerator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ import {
|
||||
import { createContextId } from '../helpers/context-id-factory';
|
||||
import { getClassScope } from '../helpers/get-class-scope';
|
||||
import { isDurable } from '../helpers/is-durable';
|
||||
import { DeterministicUuidRegistry } from '../inspector/deterministic-uuid-registry';
|
||||
import { UuidFactory } from '../inspector/uuid-factory';
|
||||
import { CONTROLLER_ID_KEY } from './constants';
|
||||
import { NestContainer } from './container';
|
||||
import { InstanceWrapper } from './instance-wrapper';
|
||||
import { ModuleRefGetOrResolveOpts, ModuleRef } from './module-ref';
|
||||
import { ModuleRef, ModuleRefGetOrResolveOpts } from './module-ref';
|
||||
|
||||
/**
|
||||
* @note
|
||||
@@ -626,8 +626,6 @@ export class Module {
|
||||
private generateUuid(): string {
|
||||
const UUID_NAMESPACE = 'fb848993-0c82-4b9e-ae95-3c3c1dbe3d6b';
|
||||
const key = this.name?.toString() ?? this.token?.toString();
|
||||
return key
|
||||
? DeterministicUuidRegistry.get(key, UUID_NAMESPACE)
|
||||
: randomStringGenerator();
|
||||
return key ? UuidFactory.get(key, UUID_NAMESPACE) : randomStringGenerator();
|
||||
}
|
||||
}
|
||||
|
||||
21
packages/core/inspector/uuid-factory.ts
Normal file
21
packages/core/inspector/uuid-factory.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { randomStringGenerator } from '../../common/utils/random-string-generator.util';
|
||||
import { DeterministicUuidRegistry } from './deterministic-uuid-registry';
|
||||
|
||||
export enum UuidFactoryMode {
|
||||
Random = 'random',
|
||||
Deterministic = 'deterministic',
|
||||
}
|
||||
|
||||
export class UuidFactory {
|
||||
private static _mode = UuidFactoryMode.Random;
|
||||
|
||||
static set mode(value: UuidFactoryMode) {
|
||||
this._mode = value;
|
||||
}
|
||||
|
||||
static get(key = '', namespace?: string) {
|
||||
return this._mode === UuidFactoryMode.Deterministic
|
||||
? DeterministicUuidRegistry.get(key, namespace)
|
||||
: randomStringGenerator();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import { ExecutionContextHost } from '../helpers/execution-context-host';
|
||||
import { STATIC_CONTEXT } from '../injector/constants';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { Injector } from '../injector/injector';
|
||||
import { InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { ContextId, InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { InstanceToken, Module } from '../injector/module';
|
||||
import { GraphInspector } from '../inspector/graph-inspector';
|
||||
import {
|
||||
@@ -250,6 +250,9 @@ export class MiddlewareModule<
|
||||
const proxy = await this.createProxy(instance);
|
||||
return this.registerHandler(applicationRef, routeInfo, proxy);
|
||||
}
|
||||
|
||||
const isTreeDurable = wrapper.isDependencyTreeDurable();
|
||||
|
||||
await this.registerHandler(
|
||||
applicationRef,
|
||||
routeInfo,
|
||||
@@ -259,19 +262,7 @@ export class MiddlewareModule<
|
||||
next: () => void,
|
||||
) => {
|
||||
try {
|
||||
const contextId = ContextIdFactory.getByRequest(req);
|
||||
if (!req[REQUEST_CONTEXT_ID]) {
|
||||
Object.defineProperty(req, REQUEST_CONTEXT_ID, {
|
||||
value: contextId,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
});
|
||||
this.container.registerRequestProvider(
|
||||
contextId.getParent ? contextId.payload : req,
|
||||
contextId,
|
||||
);
|
||||
}
|
||||
const contextId = this.getContextId(req, isTreeDurable);
|
||||
const contextInstance = await this.injector.loadPerContext(
|
||||
instance,
|
||||
moduleRef,
|
||||
@@ -325,10 +316,11 @@ export class MiddlewareModule<
|
||||
) {
|
||||
const prefix = this.config.getGlobalPrefix();
|
||||
const excludedRoutes = this.config.getGlobalPrefixOptions().exclude;
|
||||
const isAWildcard = ['*', '/*', '(.*)', '/(.*)'].includes(path);
|
||||
if (
|
||||
(Array.isArray(excludedRoutes) &&
|
||||
isRouteExcluded(excludedRoutes, path, method)) ||
|
||||
['*', '/*', '(.*)', '/(.*)'].includes(path)
|
||||
isAWildcard
|
||||
) {
|
||||
path = addLeadingSlash(path);
|
||||
} else {
|
||||
@@ -352,20 +344,36 @@ export class MiddlewareModule<
|
||||
const isMethodAll = isRequestMethodAll(method);
|
||||
const requestMethod = RequestMethod[method];
|
||||
const router = await applicationRef.createMiddlewareFactory(method);
|
||||
router(
|
||||
path,
|
||||
isMethodAll
|
||||
? proxy
|
||||
: <TRequest, TResponse>(
|
||||
req: TRequest,
|
||||
res: TResponse,
|
||||
next: () => void,
|
||||
) => {
|
||||
if (applicationRef.getRequestMethod(req) === requestMethod) {
|
||||
return proxy(req, res, next);
|
||||
}
|
||||
return next();
|
||||
},
|
||||
);
|
||||
|
||||
const middlewareFunction = isMethodAll
|
||||
? proxy
|
||||
: <TRequest, TResponse>(
|
||||
req: TRequest,
|
||||
res: TResponse,
|
||||
next: () => void,
|
||||
) => {
|
||||
if (applicationRef.getRequestMethod(req) === requestMethod) {
|
||||
return proxy(req, res, next);
|
||||
}
|
||||
return next();
|
||||
};
|
||||
|
||||
router(path, middlewareFunction);
|
||||
}
|
||||
|
||||
private getContextId(request: unknown, isTreeDurable: boolean): ContextId {
|
||||
const contextId = ContextIdFactory.getByRequest(request);
|
||||
if (!request[REQUEST_CONTEXT_ID]) {
|
||||
Object.defineProperty(request, REQUEST_CONTEXT_ID, {
|
||||
value: contextId,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
});
|
||||
|
||||
const requestProviderValue = isTreeDurable ? contextId.payload : request;
|
||||
this.container.registerRequestProvider(requestProviderValue, contextId);
|
||||
}
|
||||
return contextId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ export const mapToExcludeRoute = (
|
||||
return routes.map(({ path, method }) => ({
|
||||
pathRegex: pathToRegexp(path),
|
||||
requestMethod: method,
|
||||
path,
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
@@ -323,13 +323,20 @@ export class NestApplicationContext<
|
||||
* @param {string[]} signals The system signals it should listen to
|
||||
*/
|
||||
protected listenToShutdownSignals(signals: string[]) {
|
||||
let receivedSignal = false;
|
||||
const cleanup = async (signal: string) => {
|
||||
try {
|
||||
signals.forEach(sig => process.removeListener(sig, cleanup));
|
||||
if (receivedSignal) {
|
||||
// If we receive another signal while we're waiting
|
||||
// for the server to stop, just ignore it.
|
||||
return;
|
||||
}
|
||||
receivedSignal = true;
|
||||
await this.callDestroyHook();
|
||||
await this.callBeforeShutdownHook(signal);
|
||||
await this.dispose();
|
||||
await this.callShutdownHook(signal);
|
||||
signals.forEach(sig => process.removeListener(sig, cleanup));
|
||||
process.kill(process.pid, signal);
|
||||
} catch (err) {
|
||||
Logger.error(
|
||||
|
||||
@@ -266,6 +266,20 @@ export class NestApplication
|
||||
return this;
|
||||
}
|
||||
|
||||
public useBodyParser(...args: [any, any?]): this {
|
||||
if (!('useBodyParser' in this.httpAdapter)) {
|
||||
this.logger.warn('Your HTTP Adapter does not support `.useBodyParser`.');
|
||||
return this;
|
||||
}
|
||||
|
||||
const [parserType, ...otherArgs] = args;
|
||||
const rawBody = !!this.appOptions.rawBody;
|
||||
|
||||
this.httpAdapter.useBodyParser(...[parserType, rawBody, ...otherArgs]);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void {
|
||||
this.httpAdapter.enableCors(options);
|
||||
}
|
||||
@@ -364,11 +378,13 @@ export class NestApplication
|
||||
return {
|
||||
requestMethod: RequestMethod.ALL,
|
||||
pathRegex: pathToRegexp(addLeadingSlash(route)),
|
||||
path: route,
|
||||
};
|
||||
}
|
||||
return {
|
||||
requestMethod: route.method,
|
||||
pathRegex: pathToRegexp(addLeadingSlash(route.path)),
|
||||
path: route.path,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Injector } from './injector/injector';
|
||||
import { InstanceLoader } from './injector/instance-loader';
|
||||
import { GraphInspector } from './inspector/graph-inspector';
|
||||
import { NoopGraphInspector } from './inspector/noop-graph-inspector';
|
||||
import { UuidFactory, UuidFactoryMode } from './inspector/uuid-factory';
|
||||
import { MetadataScanner } from './metadata-scanner';
|
||||
import { NestApplication } from './nest-application';
|
||||
import { NestApplicationContext } from './nest-application-context';
|
||||
@@ -195,6 +196,10 @@ export class NestFactoryStatic {
|
||||
options: NestApplicationContextOptions = {},
|
||||
httpServer: HttpServer = null,
|
||||
) {
|
||||
UuidFactory.mode = options.snapshot
|
||||
? UuidFactoryMode.Deterministic
|
||||
: UuidFactoryMode.Random;
|
||||
|
||||
const injector = new Injector({ preview: options.preview });
|
||||
const instanceLoader = new InstanceLoader(
|
||||
container,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/core",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -36,7 +36,7 @@
|
||||
"uuid": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "^9.3.0-beta.3"
|
||||
"@nestjs/common": "9.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^9.0.0",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
|
||||
export interface ExcludeRouteMetadata {
|
||||
path: string;
|
||||
/**
|
||||
* Regular expression representing the route path.
|
||||
*/
|
||||
|
||||
@@ -13,8 +13,7 @@ import {
|
||||
import * as pathToRegexp from 'path-to-regexp';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { UnknownRequestMappingException } from '../errors/exceptions/unknown-request-mapping.exception';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { GuardsConsumer, GuardsContextCreator } from '../guards';
|
||||
import { ContextIdFactory } from '../helpers/context-id-factory';
|
||||
import { ExecutionContextHost } from '../helpers/execution-context-host';
|
||||
import {
|
||||
@@ -27,16 +26,17 @@ import { NestContainer } from '../injector/container';
|
||||
import { Injector } from '../injector/injector';
|
||||
import { ContextId, InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { Module } from '../injector/module';
|
||||
import {
|
||||
InterceptorsConsumer,
|
||||
InterceptorsContextCreator,
|
||||
} from '../interceptors';
|
||||
import { GraphInspector } from '../inspector/graph-inspector';
|
||||
import {
|
||||
Entrypoint,
|
||||
HttpEntrypointMetadata,
|
||||
} from '../inspector/interfaces/entrypoint.interface';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { MetadataScanner } from '../metadata-scanner';
|
||||
import { PipesConsumer } from '../pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '../pipes/pipes-context-creator';
|
||||
import { PipesConsumer, PipesContextCreator } from '../pipes';
|
||||
import { ExceptionsFilter } from './interfaces/exceptions-filter.interface';
|
||||
import { RoutePathMetadata } from './interfaces/route-path-metadata.interface';
|
||||
import { PathsExplorer } from './paths-explorer';
|
||||
@@ -355,13 +355,16 @@ export class RouterExplorer {
|
||||
) {
|
||||
const { instance } = instanceWrapper;
|
||||
const collection = moduleRef.controllers;
|
||||
|
||||
const isTreeDurable = instanceWrapper.isDependencyTreeDurable();
|
||||
|
||||
return async <TRequest extends Record<any, any>, TResponse>(
|
||||
req: TRequest,
|
||||
res: TResponse,
|
||||
next: () => void,
|
||||
) => {
|
||||
try {
|
||||
const contextId = this.getContextId(req);
|
||||
const contextId = this.getContextId(req, isTreeDurable);
|
||||
const contextInstance = await this.injector.loadPerContext(
|
||||
instance,
|
||||
moduleRef,
|
||||
@@ -397,6 +400,7 @@ export class RouterExplorer {
|
||||
|
||||
private getContextId<T extends Record<any, unknown> = any>(
|
||||
request: T,
|
||||
isTreeDurable: boolean,
|
||||
): ContextId {
|
||||
const contextId = ContextIdFactory.getByRequest(request);
|
||||
if (!request[REQUEST_CONTEXT_ID as any]) {
|
||||
@@ -406,10 +410,9 @@ export class RouterExplorer {
|
||||
writable: false,
|
||||
configurable: false,
|
||||
});
|
||||
this.container.registerRequestProvider(
|
||||
contextId.getParent ? contextId.payload : request,
|
||||
contextId,
|
||||
);
|
||||
|
||||
const requestProviderValue = isTreeDurable ? contextId.payload : request;
|
||||
this.container.registerRequestProvider(requestProviderValue, contextId);
|
||||
}
|
||||
return contextId;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,11 @@ import {
|
||||
PipeTransform,
|
||||
Scope,
|
||||
ValueProvider,
|
||||
Controller,
|
||||
Injectable,
|
||||
Type,
|
||||
} from '@nestjs/common/interfaces';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { Injectable } from '@nestjs/common/interfaces/injectable.interface';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util';
|
||||
import {
|
||||
isFunction,
|
||||
isNil,
|
||||
@@ -50,8 +51,8 @@ import { NestContainer } from './injector/container';
|
||||
import { InstanceWrapper } from './injector/instance-wrapper';
|
||||
import { InternalCoreModuleFactory } from './injector/internal-core-module/internal-core-module-factory';
|
||||
import { Module } from './injector/module';
|
||||
import { DeterministicUuidRegistry } from './inspector/deterministic-uuid-registry';
|
||||
import { GraphInspector } from './inspector/graph-inspector';
|
||||
import { UuidFactory } from './inspector/uuid-factory';
|
||||
import { MetadataScanner } from './metadata-scanner';
|
||||
|
||||
interface ApplicationProviderWrapper {
|
||||
@@ -410,7 +411,7 @@ export class DependenciesScanner {
|
||||
if (!providersKeys.includes(type as string)) {
|
||||
return this.container.addProvider(provider as any, token);
|
||||
}
|
||||
const uuid = DeterministicUuidRegistry.get(type.toString());
|
||||
const uuid = UuidFactory.get(type.toString());
|
||||
const providerToken = `${type as string} (UUID: ${uuid})`;
|
||||
|
||||
let scope = (provider as ClassProvider | FactoryProvider).scope;
|
||||
|
||||
@@ -23,7 +23,11 @@ describe('ApplicationConfig', () => {
|
||||
it('should set global path options', () => {
|
||||
const options: GlobalPrefixOptions<ExcludeRouteMetadata> = {
|
||||
exclude: [
|
||||
{ pathRegex: new RegExp(/health/), requestMethod: RequestMethod.GET },
|
||||
{
|
||||
pathRegex: new RegExp(/health/),
|
||||
requestMethod: RequestMethod.GET,
|
||||
path: 'health',
|
||||
},
|
||||
],
|
||||
};
|
||||
appConfig.setGlobalPrefixOptions(options);
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Injector } from '../injector/injector';
|
||||
import { InstanceLoader } from '../injector/instance-loader';
|
||||
import { GraphInspector } from '../inspector/graph-inspector';
|
||||
import { NestApplicationContext } from '../nest-application-context';
|
||||
import * as sinon from 'sinon';
|
||||
|
||||
describe('NestApplicationContext', () => {
|
||||
class A {}
|
||||
@@ -49,6 +50,54 @@ describe('NestApplicationContext', () => {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
describe('listenToShutdownSignals', () => {
|
||||
it('shutdown process should not be interrupted by another handler', async () => {
|
||||
const signal = 'SIGTERM';
|
||||
let processUp = true;
|
||||
let promisesResolved = false;
|
||||
const applicationContext = await testHelper(A, Scope.DEFAULT);
|
||||
applicationContext.enableShutdownHooks([signal]);
|
||||
|
||||
const waitProcessDown = new Promise(resolve => {
|
||||
const shutdownCleanupRef = applicationContext['shutdownCleanupRef'];
|
||||
const handler = () => {
|
||||
if (
|
||||
!process
|
||||
.listeners(signal)
|
||||
.find(handler => handler == shutdownCleanupRef)
|
||||
) {
|
||||
processUp = false;
|
||||
process.removeListener(signal, handler);
|
||||
resolve(undefined);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
process.on(signal, handler);
|
||||
});
|
||||
|
||||
// add some third party handler
|
||||
process.on(signal, signal => {
|
||||
// do some work
|
||||
process.kill(process.pid, signal);
|
||||
});
|
||||
|
||||
const hookStub = sinon
|
||||
.stub(applicationContext as any, 'callShutdownHook')
|
||||
.callsFake(async () => {
|
||||
// run some async code
|
||||
await new Promise(resolve => setImmediate(() => resolve(undefined)));
|
||||
if (processUp) {
|
||||
promisesResolved = true;
|
||||
}
|
||||
});
|
||||
process.kill(process.pid, signal);
|
||||
await waitProcessDown;
|
||||
hookStub.restore();
|
||||
expect(processUp).to.be.false;
|
||||
expect(promisesResolved).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
describe('when scope = DEFAULT', () => {
|
||||
it('should get value with function injection key', async () => {
|
||||
|
||||
@@ -249,6 +249,7 @@ describe('RoutePathFactory', () => {
|
||||
{
|
||||
pathRegex: pathToRegexp('/random'),
|
||||
requestMethod: RequestMethod.ALL,
|
||||
path: '/random',
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -267,6 +268,7 @@ describe('RoutePathFactory', () => {
|
||||
{
|
||||
pathRegex: pathToRegexp('/cats'),
|
||||
requestMethod: RequestMethod.ALL,
|
||||
path: '/cats',
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -285,6 +287,7 @@ describe('RoutePathFactory', () => {
|
||||
{
|
||||
pathRegex: pathToRegexp('/cats'),
|
||||
requestMethod: RequestMethod.GET,
|
||||
path: '/cats',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -205,13 +205,15 @@ export class ListenersController {
|
||||
const collection = moduleRef.controllers;
|
||||
const { instance } = wrapper;
|
||||
|
||||
const isTreeDurable = wrapper.isDependencyTreeDurable();
|
||||
|
||||
const requestScopedHandler: MessageHandler = async (...args: unknown[]) => {
|
||||
try {
|
||||
let contextId: ContextId;
|
||||
|
||||
let [dataOrContextHost] = args;
|
||||
if (dataOrContextHost instanceof RequestContextHost) {
|
||||
contextId = this.getContextId(dataOrContextHost);
|
||||
contextId = this.getContextId(dataOrContextHost, isTreeDurable);
|
||||
args.shift();
|
||||
} else {
|
||||
const [data, reqCtx] = args;
|
||||
@@ -220,11 +222,7 @@ export class ListenersController {
|
||||
data,
|
||||
reqCtx as BaseRpcContext,
|
||||
);
|
||||
contextId = this.getContextId(request);
|
||||
this.container.registerRequestProvider(
|
||||
contextId.getParent ? contextId.payload : request,
|
||||
contextId,
|
||||
);
|
||||
contextId = this.getContextId(request, isTreeDurable);
|
||||
dataOrContextHost = request;
|
||||
}
|
||||
const contextInstance = await this.injector.loadPerContext(
|
||||
@@ -270,7 +268,10 @@ export class ListenersController {
|
||||
return requestScopedHandler;
|
||||
}
|
||||
|
||||
private getContextId<T extends RequestContext = any>(request: T): ContextId {
|
||||
private getContextId<T extends RequestContext = any>(
|
||||
request: T,
|
||||
isTreeDurable: boolean,
|
||||
): ContextId {
|
||||
const contextId = ContextIdFactory.getByRequest(request);
|
||||
if (!request[REQUEST_CONTEXT_ID as any]) {
|
||||
Object.defineProperty(request, REQUEST_CONTEXT_ID, {
|
||||
@@ -279,10 +280,9 @@ export class ListenersController {
|
||||
writable: false,
|
||||
configurable: false,
|
||||
});
|
||||
this.container.registerRequestProvider(
|
||||
contextId.getParent ? contextId.payload : request,
|
||||
contextId,
|
||||
);
|
||||
|
||||
const requestProviderValue = isTreeDurable ? contextId.payload : request;
|
||||
this.container.registerRequestProvider(requestProviderValue, contextId);
|
||||
}
|
||||
return contextId;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/microservices",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@microservices)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -21,8 +21,8 @@
|
||||
"tslib": "2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "^9.3.0-beta.3",
|
||||
"@nestjs/core": "^9.3.0-beta.3"
|
||||
"@nestjs/common": "9.3.0",
|
||||
"@nestjs/core": "9.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@grpc/grpc-js": "*",
|
||||
|
||||
@@ -218,6 +218,8 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
|
||||
if (err instanceof KafkaRetriableException && !isPromiseResolved) {
|
||||
isPromiseResolved = true;
|
||||
reject(err);
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
replayStream$.error(err);
|
||||
},
|
||||
|
||||
@@ -29,11 +29,13 @@ import {
|
||||
OptionsUrlencoded,
|
||||
urlencoded as bodyParserUrlencoded,
|
||||
} from 'body-parser';
|
||||
import * as bodyparser from 'body-parser';
|
||||
import * as cors from 'cors';
|
||||
import * as express from 'express';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { Duplex, pipeline } from 'stream';
|
||||
import { NestExpressBodyParserOptions } from '../interfaces/nest-express-body-parser-options.interface';
|
||||
import { ServeStaticOptions } from '../interfaces/serve-static-options.interface';
|
||||
import { getBodyParserOptions } from './utils/get-body-parser-options.util';
|
||||
|
||||
@@ -235,6 +237,19 @@ export class ExpressAdapter extends AbstractHttpAdapter {
|
||||
.forEach(parserKey => this.use(parserMiddleware[parserKey]));
|
||||
}
|
||||
|
||||
public useBodyParser<Options extends bodyparser.Options = bodyparser.Options>(
|
||||
type: keyof bodyparser.BodyParser,
|
||||
rawBody: boolean,
|
||||
options?: NestExpressBodyParserOptions<Options>,
|
||||
): this {
|
||||
const parserOptions = getBodyParserOptions(rawBody, options || {});
|
||||
const parser = bodyparser[type](parserOptions);
|
||||
|
||||
this.use(parser);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public setLocal(key: string, value: any) {
|
||||
this.instance.locals[key] = value;
|
||||
return this;
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './nest-express-application.interface';
|
||||
export * from './nest-express-body-parser-options.interface';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Server } from 'net';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import * as bodyparser from 'body-parser';
|
||||
import { NestExpressBodyParserOptions } from './nest-express-body-parser-options.interface';
|
||||
import { ServeStaticOptions } from './serve-static-options.interface';
|
||||
|
||||
/**
|
||||
@@ -73,6 +75,24 @@ export interface NestExpressApplication extends INestApplication {
|
||||
*/
|
||||
useStaticAssets(path: string, options?: ServeStaticOptions): this;
|
||||
|
||||
/**
|
||||
* Register Express body parsers on the fly. Will respect
|
||||
* the application's `rawBody` option.
|
||||
*
|
||||
* @example
|
||||
* const app = await NestFactory.create<NestExpressApplication>(
|
||||
* AppModule,
|
||||
* { rawBody: true }
|
||||
* );
|
||||
* app.useBodyParser('json', { limit: '50mb' });
|
||||
*
|
||||
* @returns {this}
|
||||
*/
|
||||
useBodyParser<Options extends bodyparser.Options = bodyparser.Options>(
|
||||
parser: keyof bodyparser.BodyParser,
|
||||
options?: NestExpressBodyParserOptions<Options>,
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Sets one or multiple base directories for templates (views).
|
||||
*
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { Options } from 'body-parser';
|
||||
|
||||
export type NestExpressBodyParserOptions<T extends Options = Options> = Omit<
|
||||
T,
|
||||
'verify'
|
||||
>;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-express",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-express)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -24,8 +24,8 @@
|
||||
"tslib": "2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "^9.3.0-beta.3",
|
||||
"@nestjs/core": "^9.3.0-beta.3"
|
||||
"@nestjs/common": "9.3.0",
|
||||
"@nestjs/core": "9.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^9.0.0",
|
||||
|
||||
@@ -18,9 +18,10 @@ import { isString, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
import {
|
||||
fastify,
|
||||
FastifyBaseLogger,
|
||||
FastifyBodyParser,
|
||||
FastifyInstance,
|
||||
FastifyBaseLogger,
|
||||
FastifyListenOptions,
|
||||
FastifyPluginAsync,
|
||||
FastifyPluginCallback,
|
||||
FastifyRegister,
|
||||
@@ -45,6 +46,7 @@ import {
|
||||
} from 'light-my-request';
|
||||
// `querystring` is used internally in fastify for registering urlencoded body parser.
|
||||
import { parse as querystringParse } from 'querystring';
|
||||
import { NestFastifyBodyParserOptions } from '../interfaces';
|
||||
import {
|
||||
FastifyStaticOptions,
|
||||
FastifyViewOptions,
|
||||
@@ -227,12 +229,27 @@ export class FastifyAdapter<
|
||||
hostname: string,
|
||||
callback?: () => void,
|
||||
): void;
|
||||
public listen(port: string | number, ...args: any[]): void {
|
||||
public listen(
|
||||
listenOptions: string | number | FastifyListenOptions,
|
||||
...args: any[]
|
||||
): void {
|
||||
const isFirstArgTypeofFunction = typeof args[0] === 'function';
|
||||
const callback = isFirstArgTypeofFunction ? args[0] : args[1];
|
||||
const options: Record<string, any> = {
|
||||
port: +port,
|
||||
};
|
||||
|
||||
let options: Record<string, any>;
|
||||
if (
|
||||
typeof listenOptions === 'object' &&
|
||||
(listenOptions.host !== undefined ||
|
||||
listenOptions.port !== undefined ||
|
||||
listenOptions.path !== undefined)
|
||||
) {
|
||||
// First parameter is an object with a path, port and/or host attributes
|
||||
options = listenOptions;
|
||||
} else {
|
||||
options = {
|
||||
port: +listenOptions,
|
||||
};
|
||||
}
|
||||
if (!isFirstArgTypeofFunction) {
|
||||
options.host = args[0];
|
||||
}
|
||||
@@ -465,6 +482,43 @@ export class FastifyAdapter<
|
||||
this._isParserRegistered = true;
|
||||
}
|
||||
|
||||
public useBodyParser(
|
||||
type: string | string[] | RegExp,
|
||||
rawBody: boolean,
|
||||
options?: NestFastifyBodyParserOptions,
|
||||
parser?: FastifyBodyParser<Buffer, TServer>,
|
||||
) {
|
||||
const parserOptions = {
|
||||
...(options || {}),
|
||||
parseAs: 'buffer' as const,
|
||||
};
|
||||
|
||||
this.getInstance().addContentTypeParser<Buffer>(
|
||||
type,
|
||||
parserOptions,
|
||||
(
|
||||
req: RawBodyRequest<FastifyRequest<unknown, TServer, TRawRequest>>,
|
||||
body: Buffer,
|
||||
done,
|
||||
) => {
|
||||
if (rawBody === true && Buffer.isBuffer(body)) {
|
||||
req.rawBody = body;
|
||||
}
|
||||
|
||||
if (parser) {
|
||||
parser(req, body, done);
|
||||
return;
|
||||
}
|
||||
|
||||
done(null, body);
|
||||
},
|
||||
);
|
||||
|
||||
// To avoid the Nest application init to override our custom
|
||||
// body parser, we mark the parsers as registered.
|
||||
this._isParserRegistered = true;
|
||||
}
|
||||
|
||||
public async createMiddlewareFactory(
|
||||
requestMethod: RequestMethod,
|
||||
): Promise<(path: string, callback: Function) => any> {
|
||||
@@ -510,20 +564,15 @@ export class FastifyAdapter<
|
||||
}
|
||||
|
||||
private registerJsonContentParser(rawBody?: boolean) {
|
||||
const contentType = 'application/json';
|
||||
const withRawBody = !!rawBody;
|
||||
const { bodyLimit } = this.getInstance().initialConfig;
|
||||
|
||||
this.getInstance().addContentTypeParser<Buffer>(
|
||||
'application/json',
|
||||
{ parseAs: 'buffer', bodyLimit },
|
||||
(
|
||||
req: RawBodyRequest<FastifyRequest<unknown, TServer, TRawRequest>>,
|
||||
body: Buffer,
|
||||
done,
|
||||
) => {
|
||||
if (rawBody === true && Buffer.isBuffer(body)) {
|
||||
req.rawBody = body;
|
||||
}
|
||||
|
||||
this.useBodyParser(
|
||||
contentType,
|
||||
withRawBody,
|
||||
{ bodyLimit },
|
||||
(req, body, done) => {
|
||||
const { onProtoPoisoning, onConstructorPoisoning } =
|
||||
this.instance.initialConfig;
|
||||
const defaultJsonParser = this.instance.getDefaultJsonParser(
|
||||
@@ -536,20 +585,15 @@ export class FastifyAdapter<
|
||||
}
|
||||
|
||||
private registerUrlencodedContentParser(rawBody?: boolean) {
|
||||
const contentType = 'application/x-www-form-urlencoded';
|
||||
const withRawBody = !!rawBody;
|
||||
const { bodyLimit } = this.getInstance().initialConfig;
|
||||
|
||||
this.getInstance().addContentTypeParser<Buffer>(
|
||||
'application/x-www-form-urlencoded',
|
||||
{ parseAs: 'buffer', bodyLimit },
|
||||
(
|
||||
req: RawBodyRequest<FastifyRequest<unknown, TServer, TRawRequest>>,
|
||||
body: Buffer,
|
||||
done,
|
||||
) => {
|
||||
if (rawBody === true && Buffer.isBuffer(body)) {
|
||||
req.rawBody = body;
|
||||
}
|
||||
|
||||
this.useBodyParser(
|
||||
contentType,
|
||||
withRawBody,
|
||||
{ bodyLimit },
|
||||
(_req, body, done) => {
|
||||
done(null, querystringParse(body.toString()));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './nest-fastify-application.interface';
|
||||
export * from './nest-fastify-body-parser-options.interface';
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import {
|
||||
FastifyBodyParser,
|
||||
FastifyInstance,
|
||||
FastifyPluginAsync,
|
||||
FastifyPluginCallback,
|
||||
FastifyPluginOptions,
|
||||
FastifyRegisterOptions,
|
||||
RawServerBase,
|
||||
} from 'fastify';
|
||||
import {
|
||||
Chain as LightMyRequestChain,
|
||||
@@ -12,6 +14,7 @@ import {
|
||||
Response as LightMyRequestResponse,
|
||||
} from 'light-my-request';
|
||||
import { FastifyStaticOptions, FastifyViewOptions } from './external';
|
||||
import { NestFastifyBodyParserOptions } from './nest-fastify-body-parser-options.interface';
|
||||
|
||||
export interface NestFastifyApplication extends INestApplication {
|
||||
/**
|
||||
@@ -28,6 +31,27 @@ export interface NestFastifyApplication extends INestApplication {
|
||||
opts?: FastifyRegisterOptions<Options>,
|
||||
): Promise<FastifyInstance>;
|
||||
|
||||
/**
|
||||
* Register Fastify body parsers on the fly. Will respect
|
||||
* the application's `rawBody` option.
|
||||
*
|
||||
* @example
|
||||
* const app = await NestFactory.create<NestFastifyApplication>(
|
||||
* AppModule,
|
||||
* new FastifyAdapter(),
|
||||
* { rawBody: true }
|
||||
* );
|
||||
* // enable the json parser with a parser limit of 50mb
|
||||
* app.useBodyParser('application/json', { bodyLimit: 50 * 1000 * 1024 });
|
||||
*
|
||||
* @returns {this}
|
||||
*/
|
||||
useBodyParser<TServer extends RawServerBase = RawServerBase>(
|
||||
type: string | string[] | RegExp,
|
||||
options?: NestFastifyBodyParserOptions,
|
||||
parser?: FastifyBodyParser<Buffer, TServer>,
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Sets a base directory for public assets.
|
||||
* Example `app.useStaticAssets({ root: 'public' })`
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { AddContentTypeParser } from 'fastify';
|
||||
|
||||
export type NestFastifyBodyParserOptions = Omit<
|
||||
Parameters<AddContentTypeParser>[1],
|
||||
'parseAs'
|
||||
>;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-fastify",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-socket.io",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-socket.io)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-ws",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-ws)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/testing",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@testing)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Logger, LoggerService, Module } from '@nestjs/common';
|
||||
import { ModuleMetadata } from '@nestjs/common/interfaces';
|
||||
import { Logger, LoggerService, Module, ModuleMetadata } from '@nestjs/common';
|
||||
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
|
||||
import { ApplicationConfig } from '@nestjs/core/application-config';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
|
||||
import { NoopGraphInspector } from '@nestjs/core/inspector/noop-graph-inspector';
|
||||
import {
|
||||
UuidFactory,
|
||||
UuidFactoryMode,
|
||||
} from '@nestjs/core/inspector/uuid-factory';
|
||||
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import { DependenciesScanner } from '@nestjs/core/scanner';
|
||||
import {
|
||||
@@ -68,9 +71,14 @@ export class TestingModuleBuilder {
|
||||
): Promise<TestingModule> {
|
||||
this.applyLogger();
|
||||
|
||||
const graphInspector = options?.snapshot
|
||||
? new GraphInspector(this.container)
|
||||
: NoopGraphInspector;
|
||||
let graphInspector: GraphInspector;
|
||||
if (options?.snapshot) {
|
||||
graphInspector = new GraphInspector(this.container);
|
||||
UuidFactory.mode = UuidFactoryMode.Deterministic;
|
||||
} else {
|
||||
graphInspector = NoopGraphInspector;
|
||||
UuidFactory.mode = UuidFactoryMode.Random;
|
||||
}
|
||||
|
||||
const scanner = new DependenciesScanner(
|
||||
this.container,
|
||||
@@ -81,17 +89,7 @@ export class TestingModuleBuilder {
|
||||
await scanner.scan(this.module);
|
||||
|
||||
this.applyOverloadsMap();
|
||||
|
||||
const instanceLoader = new TestingInstanceLoader(
|
||||
this.container,
|
||||
this.injector,
|
||||
graphInspector,
|
||||
);
|
||||
await instanceLoader.createInstancesOfDependencies(
|
||||
this.container.getModules(),
|
||||
this.mocker,
|
||||
);
|
||||
|
||||
await this.createInstancesOfDependencies(graphInspector);
|
||||
scanner.applyApplicationProviders();
|
||||
|
||||
const root = this.getRootModule();
|
||||
@@ -136,6 +134,18 @@ export class TestingModuleBuilder {
|
||||
return modules.next().value;
|
||||
}
|
||||
|
||||
private async createInstancesOfDependencies(graphInspector: GraphInspector) {
|
||||
const instanceLoader = new TestingInstanceLoader(
|
||||
this.container,
|
||||
this.injector,
|
||||
graphInspector,
|
||||
);
|
||||
await instanceLoader.createInstancesOfDependencies(
|
||||
this.container.getModules(),
|
||||
this.mocker,
|
||||
);
|
||||
}
|
||||
|
||||
private createModule(metadata: ModuleMetadata) {
|
||||
class RootTestModule {}
|
||||
Module(metadata)(RootTestModule);
|
||||
|
||||
@@ -18,10 +18,11 @@ import {
|
||||
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
||||
import { HandlerMetadataStorage } from '@nestjs/core/helpers/handler-metadata-storage';
|
||||
import { ParamsMetadata } from '@nestjs/core/helpers/interfaces';
|
||||
import { InterceptorsConsumer } from '@nestjs/core/interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '@nestjs/core/pipes/pipes-context-creator';
|
||||
import {
|
||||
InterceptorsConsumer,
|
||||
InterceptorsContextCreator,
|
||||
} from '@nestjs/core/interceptors';
|
||||
import { PipesConsumer, PipesContextCreator } from '@nestjs/core/pipes';
|
||||
import { PARAM_ARGS_METADATA } from '../constants';
|
||||
import { WsException } from '../errors/ws-exception';
|
||||
import { WsParamsFactory } from '../factories/ws-params-factory';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/websockets",
|
||||
"version": "9.3.0-beta.3",
|
||||
"version": "9.3.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@websockets)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -17,8 +17,8 @@
|
||||
"tslib": "2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "^9.3.0-beta.3",
|
||||
"@nestjs/core": "^9.3.0-beta.3"
|
||||
"@nestjs/common": "9.3.0",
|
||||
"@nestjs/core": "9.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^9.0.0",
|
||||
|
||||
48
sample/01-cats-app/package-lock.json
generated
48
sample/01-cats-app/package-lock.json
generated
@@ -1440,9 +1440,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cli/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -3792,9 +3792,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -5957,9 +5957,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
@@ -8076,9 +8076,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -9654,9 +9654,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -11547,9 +11547,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -13079,9 +13079,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonc-parser": {
|
||||
@@ -14619,9 +14619,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
|
||||
62
sample/02-gateways/package-lock.json
generated
62
sample/02-gateways/package-lock.json
generated
@@ -1365,9 +1365,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cli/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -3843,9 +3843,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -5990,9 +5990,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
@@ -6376,12 +6376,6 @@
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/node-emoji/node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
@@ -8153,9 +8147,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -9711,9 +9705,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -11689,9 +11683,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -13236,9 +13230,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonc-parser": {
|
||||
@@ -13530,14 +13524,6 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
@@ -14824,9 +14810,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
|
||||
62
sample/03-microservices/package-lock.json
generated
62
sample/03-microservices/package-lock.json
generated
@@ -1349,9 +1349,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cli/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -3709,9 +3709,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -5841,9 +5841,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
@@ -6227,12 +6227,6 @@
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/node-emoji/node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
@@ -7956,9 +7950,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -9472,9 +9466,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -11332,9 +11326,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -12867,9 +12861,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonc-parser": {
|
||||
@@ -13161,14 +13155,6 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
@@ -14415,9 +14401,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
|
||||
62
sample/04-grpc/package-lock.json
generated
62
sample/04-grpc/package-lock.json
generated
@@ -1429,9 +1429,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cli/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -3839,9 +3839,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -6060,9 +6060,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
@@ -6462,12 +6462,6 @@
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/node-emoji/node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
@@ -8147,9 +8141,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -9717,9 +9711,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -11606,9 +11600,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -13228,9 +13222,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonc-parser": {
|
||||
@@ -13540,14 +13534,6 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
@@ -14755,9 +14741,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
|
||||
Reference in New Issue
Block a user