mirror of
https://github.com/nestjs/nest.git
synced 2026-02-24 00:02:56 +00:00
Compare commits
22 Commits
feature/as
...
v5.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acf97a2e1d | ||
|
|
84c156356b | ||
|
|
9a3f760b6c | ||
|
|
d1ad94324b | ||
|
|
69fb434def | ||
|
|
6fc4826b30 | ||
|
|
2f888d3abe | ||
|
|
0db05f62f1 | ||
|
|
255ca7ef99 | ||
|
|
6744a8648d | ||
|
|
7a0808ed5b | ||
|
|
1b872d66b7 | ||
|
|
0f788efd0c | ||
|
|
72491e7d62 | ||
|
|
4b74c275bd | ||
|
|
3939a67bd3 | ||
|
|
94679b2d79 | ||
|
|
83fc4c3bc4 | ||
|
|
69f2f3dd0b | ||
|
|
b49a9a1098 | ||
|
|
2a5e22e2c6 | ||
|
|
ff2e310a18 |
@@ -16,6 +16,7 @@
|
||||
<a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a>
|
||||
<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#8" alt="Coverage" /></a>
|
||||
<a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a>
|
||||
<a href="https://discord.gg/G7Qnnhy"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
||||
<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||
<a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||
<a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
|
||||
@@ -48,13 +49,10 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
<a href="https://valor-software.com/"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="320" /></a>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="220" /></a>
|
||||
|
||||
#### Silver Sponsors
|
||||
<a href="https://neoteric.eu/"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" /></a>
|
||||
<a href="http://gojob.com"><img src="http://nestjs.com/img/gojob-logo.png" valign="bottom" height="95" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /> </a>
|
||||
<a href="http://gojob.com"><img src="http://nestjs.com/img/gojob-logo.png" valign="bottom" height="95" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /> </a>
|
||||
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="150" /></a>
|
||||
|
||||
#### Sponsors
|
||||
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "5.5.0"
|
||||
"version": "5.6.0"
|
||||
}
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nestjs",
|
||||
"version": "5.4.0",
|
||||
"version": "5.4.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
49
package.json
49
package.json
@@ -5,30 +5,21 @@
|
||||
"scripts": {
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||
"precommit": "lint-staged",
|
||||
"test":
|
||||
"nyc --require ts-node/register mocha packages/**/*.spec.ts --reporter spec --require 'node_modules/reflect-metadata/Reflect.js'",
|
||||
"integration-test":
|
||||
"mocha integration/**/*.spec.ts --reporter spec --require ts-node/register --require 'node_modules/reflect-metadata/Reflect.js'",
|
||||
"lint":
|
||||
"tslint -p tsconfig.json -c tslint.json \"packages/**/*.ts\" -e \"*.spec.ts\"",
|
||||
"format":
|
||||
"prettier **/**/*.ts --ignore-path ./.prettierignore --write && git status",
|
||||
"test": "nyc --require ts-node/register mocha packages/**/*.spec.ts --reporter spec --require 'node_modules/reflect-metadata/Reflect.js'",
|
||||
"integration-test": "mocha integration/**/*.spec.ts --reporter spec --require ts-node/register --require 'node_modules/reflect-metadata/Reflect.js'",
|
||||
"lint": "tslint -p tsconfig.json -c tslint.json \"packages/**/*.ts\" -e \"*.spec.ts\"",
|
||||
"format": "prettier **/**/*.ts --ignore-path ./.prettierignore --write && git status",
|
||||
"clean": "gulp clean:bundle",
|
||||
"build": "npm run clean && gulp build",
|
||||
"prebuild:dev": "rm -rf node_modules/@nestjs",
|
||||
"build:dev": "gulp build --dist node_modules/@nestjs && gulp move",
|
||||
"postinstall": "opencollective",
|
||||
"prerelease": "gulp copy-misc && gulp build --dist node_modules/@nestjs",
|
||||
"publish":
|
||||
"npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --force-publish --exact -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:rc":
|
||||
"npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=rc -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:next":
|
||||
"npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=next --skip-git -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:beta":
|
||||
"npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=beta -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:test":
|
||||
"npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --force-publish --npm-tag=test --skip-git -m \"chore(@nestjs) publish %s release\""
|
||||
"publish": "npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --force-publish --exact -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:rc": "npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=rc -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:next": "npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=next --skip-git -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:beta": "npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --npm-tag=beta -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:test": "npm run prerelease && npm run build && ./node_modules/.bin/lerna publish --force-publish --npm-tag=test --skip-git -m \"chore(@nestjs) publish %s release\""
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.9.0"
|
||||
@@ -141,7 +132,9 @@
|
||||
}
|
||||
},
|
||||
"nyc": {
|
||||
"include": ["packages/**/*.ts"],
|
||||
"include": [
|
||||
"packages/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules/",
|
||||
"packages/**/*.spec.ts",
|
||||
@@ -161,13 +154,23 @@
|
||||
"packages/common/serializer/**/*",
|
||||
"packages/common/services/logger.service.ts"
|
||||
],
|
||||
"extension": [".ts"],
|
||||
"require": ["ts-node/register"],
|
||||
"reporter": ["text-summary", "html"],
|
||||
"extension": [
|
||||
".ts"
|
||||
],
|
||||
"require": [
|
||||
"ts-node/register"
|
||||
],
|
||||
"reporter": [
|
||||
"text-summary",
|
||||
"html"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"instrument": true
|
||||
},
|
||||
"lint-staged": {
|
||||
"packages/**/*.{ts,json}": ["npm run format", "git add"]
|
||||
"packages/**/*.{ts,json}": [
|
||||
"npm run format",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/common",
|
||||
"version": "5.5.0",
|
||||
"version": "5.6.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@common)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"repository": {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
ValidationError,
|
||||
} from '../index';
|
||||
import { ValidatorOptions } from '../interfaces/external/validator-options.interface';
|
||||
import { ClassTransformOptions } from '../interfaces/external/class-transform-options.interface';
|
||||
import { PipeTransform } from '../interfaces/features/pipe-transform.interface';
|
||||
import { loadPackage } from '../utils/load-package.util';
|
||||
import { isNil } from '../utils/shared.utils';
|
||||
@@ -13,6 +14,7 @@ import { isNil } from '../utils/shared.utils';
|
||||
export interface ValidationPipeOptions extends ValidatorOptions {
|
||||
transform?: boolean;
|
||||
disableErrorMessages?: boolean;
|
||||
transformOptions?: ClassTransformOptions;
|
||||
exceptionFactory?: (errors: ValidationError[]) => any;
|
||||
}
|
||||
|
||||
@@ -24,13 +26,20 @@ export class ValidationPipe implements PipeTransform<any> {
|
||||
protected isTransformEnabled: boolean;
|
||||
protected isDetailedOutputDisabled?: boolean;
|
||||
protected validatorOptions: ValidatorOptions;
|
||||
protected transformOptions: ClassTransformOptions;
|
||||
protected exceptionFactory: (errors: ValidationError[]) => any;
|
||||
|
||||
constructor(@Optional() options?: ValidationPipeOptions) {
|
||||
options = options || {};
|
||||
const { transform, disableErrorMessages, ...validatorOptions } = options;
|
||||
const {
|
||||
transform,
|
||||
disableErrorMessages,
|
||||
transformOptions,
|
||||
...validatorOptions
|
||||
} = options;
|
||||
this.isTransformEnabled = !!transform;
|
||||
this.validatorOptions = validatorOptions;
|
||||
this.transformOptions = transformOptions;
|
||||
this.isDetailedOutputDisabled = disableErrorMessages;
|
||||
this.exceptionFactory =
|
||||
options.exceptionFactory ||
|
||||
@@ -52,6 +61,7 @@ export class ValidationPipe implements PipeTransform<any> {
|
||||
const entity = classTransformer.plainToClass(
|
||||
metatype,
|
||||
this.toEmptyIfNil(value),
|
||||
this.transformOptions
|
||||
);
|
||||
const errors = await classValidator.validate(entity, this.validatorOptions);
|
||||
if (errors.length > 0) {
|
||||
@@ -60,8 +70,8 @@ export class ValidationPipe implements PipeTransform<any> {
|
||||
return this.isTransformEnabled
|
||||
? entity
|
||||
: Object.keys(this.validatorOptions).length > 0
|
||||
? classTransformer.classToPlain(entity)
|
||||
: value;
|
||||
? classTransformer.classToPlain(entity, this.transformOptions)
|
||||
: value;
|
||||
}
|
||||
|
||||
private toValidate(metadata: ArgumentMetadata): boolean {
|
||||
|
||||
@@ -1,9 +1,26 @@
|
||||
import * as sinon from 'sinon';
|
||||
import { expect } from 'chai';
|
||||
import { Exclude, Expose } from 'class-transformer';
|
||||
import { IsOptional, IsString } from 'class-validator';
|
||||
import { ArgumentMetadata } from '../../interfaces';
|
||||
import { IsString } from 'class-validator';
|
||||
import { ValidationPipe } from '../../pipes/validation.pipe';
|
||||
|
||||
@Exclude()
|
||||
class TestModelInternal {
|
||||
constructor() {}
|
||||
@Expose()
|
||||
@IsString()
|
||||
public prop1: string;
|
||||
|
||||
@Expose()
|
||||
@IsString()
|
||||
public prop2: string;
|
||||
|
||||
@Expose({ groups: ['internal'] })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
public propInternal: string;
|
||||
}
|
||||
|
||||
class TestModel {
|
||||
constructor() {}
|
||||
@IsString() public prop1: string;
|
||||
@@ -18,6 +35,11 @@ describe('ValidationPipe', () => {
|
||||
metatype: TestModel,
|
||||
data: '',
|
||||
};
|
||||
const transformMetadata: ArgumentMetadata = {
|
||||
type: 'body',
|
||||
metatype: TestModelInternal,
|
||||
data: '',
|
||||
};
|
||||
|
||||
describe('transform', () => {
|
||||
describe('when validation passes', () => {
|
||||
@@ -68,8 +90,40 @@ describe('ValidationPipe', () => {
|
||||
expect(target.transform(testObj, metadata)).to.eventually.throw;
|
||||
});
|
||||
});
|
||||
describe('when transformation is internal', () => {
|
||||
it('should return a TestModel with internal property', async () => {
|
||||
target = new ValidationPipe({
|
||||
transform: true,
|
||||
transformOptions: { groups: ['internal'] },
|
||||
});
|
||||
const testObj = {
|
||||
prop1: 'value1',
|
||||
prop2: 'value2',
|
||||
propInternal: 'value3',
|
||||
};
|
||||
expect(
|
||||
await target.transform(testObj, transformMetadata),
|
||||
).to.have.property('propInternal');
|
||||
});
|
||||
});
|
||||
describe('when transformation is external', () => {
|
||||
it('should return a TestModel without internal property', async () => {
|
||||
target = new ValidationPipe({
|
||||
transform: true,
|
||||
transformOptions: { groups: ['external'] },
|
||||
});
|
||||
const testObj = {
|
||||
prop1: 'value1',
|
||||
prop2: 'value2',
|
||||
propInternal: 'value3',
|
||||
};
|
||||
expect(
|
||||
await target.transform(testObj, transformMetadata),
|
||||
).to.not.have.property('propInternal');
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("when validation doesn't transform", () => {
|
||||
describe('when validation doesn\'t transform', () => {
|
||||
describe('when validation strips', () => {
|
||||
it('should return a plain object without extra properties', async () => {
|
||||
target = new ValidationPipe({ transform: false, whitelist: true });
|
||||
|
||||
@@ -53,7 +53,7 @@ export const INVALID_MIDDLEWARE_MESSAGE = (text, name: string) =>
|
||||
`The middleware doesn't provide the 'resolve' method (${name})`;
|
||||
|
||||
export const INVALID_MODULE_MESSAGE = (text, scope: string) =>
|
||||
`Nest cannot create the module instance. Often, this is because of a circular dependency between modules. Use forwardRef() to avoid it. (Read more https://docs.nestjs.com/advanced/circular-dependency.) Scope [${scope}]`;
|
||||
`Nest cannot create the module instance. Often, this is because of a circular dependency between modules. Use forwardRef() to avoid it. (Read more https://docs.nestjs.com/fundamentals/circular-dependency.) Scope [${scope}]`;
|
||||
|
||||
export const UNKNOWN_EXPORT_MESSAGE = (text, module: string) =>
|
||||
`Nest cannot export a component/module that is not a part of the currently processed module (${module}). Please verify whether each exported unit is available in this particular context.`;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Type } from '@nestjs/common';
|
||||
import { Abstract } from '@nestjs/common/interfaces';
|
||||
import { isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { UnknownElementException } from '../errors/exceptions/unknown-element.exception';
|
||||
import { InstanceWrapper, NestContainer } from './container';
|
||||
@@ -10,7 +11,7 @@ export class ContainerScanner {
|
||||
constructor(private readonly container: NestContainer) {}
|
||||
|
||||
public find<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
typeOrToken: Type<TInput> | Abstract<TInput> | string | symbol,
|
||||
): TResult {
|
||||
this.initFlatContainer();
|
||||
return this.findInstanceByPrototypeOrToken<TInput, TResult>(
|
||||
@@ -20,7 +21,7 @@ export class ContainerScanner {
|
||||
}
|
||||
|
||||
public findInstanceByPrototypeOrToken<TInput = any, TResult = TInput>(
|
||||
metatypeOrToken: Type<TInput> | string | symbol,
|
||||
metatypeOrToken: Type<TInput> | Abstract<TInput> | string | symbol,
|
||||
contextModule: Partial<Module>,
|
||||
): TResult {
|
||||
const dependencies = new Map([
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
OnModuleDestroy,
|
||||
OnModuleInit,
|
||||
} from '@nestjs/common';
|
||||
import { Abstract } from '@nestjs/common/interfaces';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
@@ -46,7 +47,7 @@ export class NestApplicationContext implements INestApplicationContext {
|
||||
}
|
||||
|
||||
public get<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
typeOrToken: Type<TInput> | Abstract<TInput> | string | symbol,
|
||||
options: { strict: boolean } = { strict: false },
|
||||
): TResult {
|
||||
if (!(options && options.strict)) {
|
||||
@@ -170,13 +171,13 @@ export class NestApplicationContext implements INestApplicationContext {
|
||||
}
|
||||
|
||||
protected find<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
typeOrToken: Type<TInput> | Abstract<TInput> | string | symbol,
|
||||
): TResult {
|
||||
return this.containerScanner.find<TInput, TResult>(typeOrToken);
|
||||
}
|
||||
|
||||
protected findInstanceByPrototypeOrToken<TInput = any, TResult = TInput>(
|
||||
metatypeOrToken: Type<TInput> | string | symbol,
|
||||
metatypeOrToken: Type<TInput> | Abstract<TInput> | string | symbol,
|
||||
contextModule: Partial<Module>,
|
||||
): TResult {
|
||||
return this.containerScanner.findInstanceByPrototypeOrToken<
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/core",
|
||||
"version": "5.5.0",
|
||||
"version": "5.6.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/microservices",
|
||||
"version": "5.5.0",
|
||||
"version": "5.6.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@microservices)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/testing",
|
||||
"version": "5.5.0",
|
||||
"version": "5.6.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@testing)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface GatewayMetadata {
|
||||
namespace?: string;
|
||||
namespace?: string | RegExp;
|
||||
path?: string;
|
||||
serveClient?: boolean;
|
||||
adapter?: any;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/websockets",
|
||||
"version": "5.5.0",
|
||||
"version": "5.6.0",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@websockets)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
Body,
|
||||
Catch,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
@@ -17,7 +16,6 @@ import { CatsService } from './cats.service';
|
||||
import { CreateCatDto } from './dto/create-cat.dto';
|
||||
import { Cat } from './interfaces/cat.interface';
|
||||
|
||||
@Catch()
|
||||
@Controller('cats')
|
||||
@UseGuards(RolesGuard)
|
||||
@UseInterceptors(LoggingInterceptor, TransformInterceptor)
|
||||
|
||||
@@ -9,7 +9,7 @@ export class CatsController {
|
||||
|
||||
@Post()
|
||||
async create(@Body() createCatDto: CreateCatDto) {
|
||||
this.catsService.create(createCatDto);
|
||||
await this.catsService.create(createCatDto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 1. Install all dependencies
|
||||
for D in integration/*; do [ -d "${D}" ] && npm i; done
|
||||
for D in integration/*/; do sh -c "cd ${D} && npm i"; done
|
||||
|
||||
# 2. Build fresh packages and move them to sample and integration directories
|
||||
npm run build:dev &>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user