Compare commits

...

22 Commits

Author SHA1 Message Date
Kamil Myśliwiec
acf97a2e1d chore(@nestjs) publish v5.6.0 release 2019-01-16 21:36:15 +01:00
Kamil Myśliwiec
84c156356b feature(websockets) support regexp in namespaces 2019-01-16 21:34:18 +01:00
Kamil Myśliwiec
9a3f760b6c bugfix(core) fix missing abstract type typing 2019-01-16 21:33:53 +01:00
Kamil Myśliwiec
d1ad94324b feature() support abstract classes in nest ctx 2019-01-16 21:15:29 +01:00
Kamil Myśliwiec
69fb434def Merge branch 'master' of https://github.com/nestjs/nest 2019-01-16 21:05:10 +01:00
Kamil Myśliwiec
6fc4826b30 Merge branch 'FionaLovett-validate-transform' 2019-01-16 20:59:29 +01:00
Kamil Myśliwiec
2f888d3abe refactor() adjust code style 2019-01-16 20:59:06 +01:00
Kamil Myśliwiec
0db05f62f1 Merge branch 'validate-transform' of https://github.com/FionaLovett/nest into FionaLovett-validate-transform 2019-01-16 20:55:36 +01:00
Kamil Mysliwiec
255ca7ef99 Merge pull request #1448 from caohuilin/patch-2
sample(mongoose) should await on create POST
2019-01-16 20:51:50 +01:00
Kamil Mysliwiec
6744a8648d Update Readme.md 2019-01-16 20:35:19 +01:00
Belinda Cao
7a0808ed5b Update cats.controller.ts 2019-01-15 09:57:06 +08:00
Kamil Mysliwiec
1b872d66b7 Update Readme.md 2019-01-15 00:12:24 +01:00
Kamil Mysliwiec
0f788efd0c Merge pull request #1441 from iblamefish/circular-dependency-message
bugfix(core) update URL for circular dependency in the error message
2019-01-14 23:17:34 +01:00
Kamil Mysliwiec
72491e7d62 Merge pull request #1410 from BrunnerLivio/feature/discord-badge
chore() add discord badge to README.md
2019-01-14 22:06:00 +01:00
Clinton Montague
4b74c275bd bugfix(core) update url for circular dependency in error message
Fixes the url in INVALID_MODULE_MESSAGE

This closes #1369
2019-01-13 17:50:03 +00:00
Livio
3939a67bd3 chore: add discord badge to README.md 2019-01-07 18:48:39 +01:00
Fiona Lovett
94679b2d79 feature(common): add transformOptions to ValidationPipeOptions
allows plainToClass to expose class properties to defined groups as per issue #1374
2019-01-02 20:52:29 +01:00
Fiona Lovett
83fc4c3bc4 feature(common): add transformOptions to ValidationPipeOptions
allows plainToClass to expose class properties to defined groups as per issue #1374
2019-01-02 20:07:50 +01:00
Fiona Lovett
69f2f3dd0b feature(common): add transformOptions to ValidationPipeOptions
allows plainToClass to expose class properties to defined groups as per issue #1374
2019-01-02 19:56:33 +01:00
Fiona Lovett
b49a9a1098 feature(common): add transformOptions to ValidationPipeOptions
allows plainToClass to expose class properties to defined groups as per issue #1374
2019-01-02 17:53:46 +01:00
Kamil Myśliwiec
2a5e22e2c6 scripts() fix prepare script (install all deps) 2018-12-29 10:21:18 +01:00
Kamil Mysliwiec
ff2e310a18 Update cats.controller.ts 2018-12-12 14:24:41 +01:00
18 changed files with 117 additions and 52 deletions

View File

@@ -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> &nbsp;
<a href="http://gojob.com"><img src="http://nestjs.com/img/gojob-logo.png" valign="bottom" height="95" /></a> &nbsp; <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> &nbsp; <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /> </a> &nbsp;
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="150" /></a>
#### Sponsors

View File

@@ -3,5 +3,5 @@
"packages": [
"packages/*"
],
"version": "5.5.0"
"version": "5.6.0"
}

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "nestjs",
"version": "5.4.0",
"version": "5.4.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -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"
]
}
}

View File

@@ -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": {

View File

@@ -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 {

View File

@@ -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 });

View File

@@ -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.`;

View File

@@ -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([

View File

@@ -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<

View File

@@ -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",

View File

@@ -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",

View File

@@ -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",

View File

@@ -1,5 +1,5 @@
export interface GatewayMetadata {
namespace?: string;
namespace?: string | RegExp;
path?: string;
serveClient?: boolean;
adapter?: any;

View File

@@ -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",

View File

@@ -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)

View File

@@ -9,7 +9,7 @@ export class CatsController {
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
await this.catsService.create(createCatDto);
}
@Get()

View File

@@ -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