Compare commits

...

42 Commits

Author SHA1 Message Date
Kamil Myśliwiec
79fc37f093 chore(@nestjs) publish v5.6.2 release 2019-01-16 22:45:26 +01:00
Kamil Myśliwiec
8eedff85bd chore() publish 5.6.1 release 2019-01-16 21:47:30 +01:00
Kamil Myśliwiec
159a947f1b chore(@nestjs) publish v5.6.1 release 2019-01-16 21:46:35 +01:00
Kamil Myśliwiec
5eee77ea20 Merge branch '5.6.0' 2019-01-16 21:39:08 +01:00
Kamil Myśliwiec
c90b8e3d07 chore() publish 5.6.0 release 2019-01-16 21:37:29 +01:00
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
c448e56611 chore() merge changes 2019-01-16 21:04:02 +01:00
Kamil Myśliwiec
b8e6553a06 Merge branch 'FionaLovett-validate-transform' into 5.6.0 2019-01-16 21:00:19 +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
5940ec7d62 Merge pull request #1388 from hschiavone/grpc-server-max-received-and-send-message-length
feature(microservices) add server gRPC max received & message length options
2019-01-15 00:30:02 +01:00
Kamil Mysliwiec
535c881a95 Merge branch '5.6.0' into grpc-server-max-received-and-send-message-length 2019-01-15 00:29:17 +01:00
Kamil Mysliwiec
986ad4e746 Merge pull request #1424 from quaternion/master
bugfix(common) add missing axios provider in HttpModule.registerAsync
2019-01-15 00:26:41 +01:00
Kamil Myśliwiec
6204fe1a09 Merge branch 'anton-alation-feature/grpc-method-with-namespaces' into 5.6.0 2019-01-15 00:25:16 +01:00
Kamil Myśliwiec
3cb73111bf refactor() adjust code style 2019-01-15 00:23:18 +01:00
Kamil Mysliwiec
1b872d66b7 Update Readme.md 2019-01-15 00:12:24 +01:00
Kamil Myśliwiec
891de8eea8 Merge branch 'feature/grpc-method-with-namespaces' of https://github.com/anton-alation/nest into anton-alation-feature/grpc-method-with-namespaces 2019-01-15 00:03:29 +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
Andrew Nikolaev
1212c6034a fix(common): add missing axios provider in HttpModule.registerAsync 2019-01-05 18:46:53 +03: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
Hugo Schiavone
84e4bdef1e fix getOptionsProp method 2018-12-27 18:25:43 +01:00
Hugo Schiavone
da110d01dd use getOptionsProp method on grcp max_send_message_length & max_receive_message_length implementation 2018-12-27 12:24:38 +01:00
Hugo Schiavone
bd3222ad62 implement server grpc max received & send message length option 2018-12-20 10:10:16 +01:00
Anton Repin
595bc988ec GRPC Server test stub updated to match getServiceNames new output 2018-12-12 15:50:10 -08:00
Anton Repin
ea26100ec3 GRPC server tests updated:
- Added package recursive search test for support of proto-namespaces
- Updated tests which were testing single level proto structure
2018-12-12 13:27:06 -08:00
Kamil Mysliwiec
ff2e310a18 Update cats.controller.ts 2018-12-12 14:24:41 +01:00
Anton Repin
8d41edadce GRPC Server namespaces support added for loaded proto descriptors
- Recursive scan of descriptors object
- Service names with namespaces concatenated with dot-syntax
2018-12-11 23:37:38 -08:00
31 changed files with 314 additions and 7552 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.2"
}

54
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "nestjs",
"version": "5.4.0",
"version": "5.6.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -111,20 +111,32 @@
}
},
"@nestjs/common": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-5.1.0.tgz",
"integrity": "sha512-JAZFqdU+f4DRE4yOvpfWDtwgmCavyfE2Vu7mSwYsklU9TlBBE9XBygN2J38aQC83dmCJ1H889shd+hBIiVyEXA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-5.5.0.tgz",
"integrity": "sha512-Ifh1D4ypsJYs/3YBIocU+X5yuAZSVKuCsz8kaKB4ZUO5WwJjh4/x6hlr4A+9XUMe8fPLtYXVohJoRUU5HbwyIA==",
"requires": {
"axios": "0.17.1",
"axios": "0.18.0",
"cli-color": "1.2.0",
"deprecate": "1.0.0",
"multer": "1.3.0"
"multer": "1.3.0",
"uuid": "3.3.2"
},
"dependencies": {
"axios": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
"requires": {
"follow-redirects": "^1.3.0",
"is-buffer": "^1.1.5"
}
}
}
},
"@nestjs/core": {
"version": "5.3.15",
"resolved": "https://registry.npmjs.org/@nestjs/core/-/core-5.3.15.tgz",
"integrity": "sha512-pbF+e7JTBxiR+vu6VmrXsP9UQqBkQrH7o6HHQdovCP1Q2/NEBhpFvzMC3mWo0/4J11qTCN06vc6sWjstpX1fMg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@nestjs/core/-/core-5.5.0.tgz",
"integrity": "sha512-XPUjSJyex6KMdTUKK1oeD7ea9mNLcwlSEbcKV7OWaNHIVq/XJaFpbzjbmd+/U/ZZaO1IWhpisfLW9gr/O8eb4w==",
"requires": {
"@nuxtjs/opencollective": "0.1.0",
"body-parser": "1.18.3",
@@ -159,7 +171,7 @@
},
"express": {
"version": "4.16.3",
"resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz",
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"requires": {
"accepts": "~1.3.5",
@@ -225,7 +237,7 @@
},
"finalhandler": {
"version": "1.1.1",
"resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
@@ -243,16 +255,16 @@
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
},
"mime-db": {
"version": "1.36.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
"version": "1.37.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
},
"mime-types": {
"version": "2.1.20",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
"version": "2.1.21",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
"requires": {
"mime-db": "~1.36.0"
"mime-db": "~1.37.0"
}
},
"proxy-addr": {
@@ -328,9 +340,9 @@
}
},
"@nestjs/microservices": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-5.1.0.tgz",
"integrity": "sha512-g9ez7N+QgjlJSSak27KhUHXi1YMnk/DuGpAn/TWlm5rSmcsrArdTSvinGBMyb0mL3CMJJz8y0/CZwAUdy9HQzA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-5.5.0.tgz",
"integrity": "sha512-sOZ2+dPxHvb+RNbmn4wo+MFg9ZHxx9N9RGZmlYQEJQ+s4zk0rJBalzJhKNuNkiL6oJDYYNom98YhWRVvuAkvwg==",
"requires": {
"iterare": "0.0.8",
"json-socket": "^0.2.1",

View File

@@ -1,6 +1,6 @@
{
"name": "nestjs",
"version": "5.4.1",
"version": "5.6.1",
"description": "Modern, fast, powerful node.js web framework",
"scripts": {
"coverage": "nyc report --reporter=text-lcov | coveralls",
@@ -41,9 +41,9 @@
"license": "MIT",
"dependencies": {
"@grpc/proto-loader": "^0.3.0",
"@nestjs/common": "5.1.0",
"@nestjs/core": "^5.3.10",
"@nestjs/microservices": "5.1.0",
"@nestjs/common": "5.5.0",
"@nestjs/core": "^5.5.0",
"@nestjs/microservices": "5.5.0",
"@nestjs/testing": "5.1.0",
"@nestjs/websockets": "5.1.0",
"@nuxtjs/opencollective": "^0.1.0",

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

@@ -47,6 +47,11 @@ export class HttpModule {
imports: options.imports,
providers: [
...this.createAsyncProviders(options),
{
provide: AXIOS_INSTANCE_TOKEN,
useFactory: (config: HttpModuleOptions) => Axios.create(config),
inject: [HTTP_MODULE_OPTIONS],
},
{
provide: HTTP_MODULE_ID,
useValue: randomStringGenerator(),

View File

@@ -20,6 +20,8 @@ export interface GrpcOptions {
transport?: Transport.GRPC;
options: {
url?: string;
maxSendMessageLength?: number;
maxReceiveMessageLength?: number;
credentials?: any;
protoPath: string;
package: string;

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/common",
"version": "5.5.0",
"version": "5.6.2",
"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

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

@@ -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.2",
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
"author": "Kamil Mysliwiec",
"license": "MIT",

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

@@ -27,3 +27,5 @@ export const RQM_DEFAULT_IS_GLOBAL_PREFETCH_COUNT = false;
export const RQM_DEFAULT_QUEUE_OPTIONS = {};
export const GRPC_DEFAULT_PROTO_LOADER = '@grpc/proto-loader';
export const GRPC_DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024;
export const GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH = 4 * 1024 * 1024;

View File

@@ -21,6 +21,8 @@ export interface GrpcOptions {
transport?: Transport.GRPC;
options: {
url?: string;
maxSendMessageLength?: number;
maxReceiveMessageLength?: number;
credentials?: any;
protoPath: string;
package: string;

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/microservices",
"version": "5.5.0",
"version": "5.6.2",
"description": "Nest - modern, fast, powerful node.js web framework (@microservices)",
"author": "Kamil Mysliwiec",
"license": "MIT",

View File

@@ -1,6 +1,13 @@
import { isObject, isUndefined } from '@nestjs/common/utils/shared.utils';
import { fromEvent } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CANCEL_EVENT, GRPC_DEFAULT_PROTO_LOADER, GRPC_DEFAULT_URL } from '../constants';
import {
CANCEL_EVENT,
GRPC_DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH,
GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH,
GRPC_DEFAULT_PROTO_LOADER,
GRPC_DEFAULT_URL
} from '../constants';
import { InvalidGrpcPackageException } from '../exceptions/errors/invalid-grpc-package.exception';
import { InvalidProtoDefinitionException } from '../exceptions/errors/invalid-proto-definition.exception';
import { CustomTransportStrategy } from '../interfaces';
@@ -23,13 +30,11 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
this.getOptionsProp<GrpcOptions>(options, 'url') || GRPC_DEFAULT_URL;
const protoLoader =
this.getOptionsProp<GrpcOptions>(options, 'protoLoader') || GRPC_DEFAULT_PROTO_LOADER;
this.getOptionsProp<GrpcOptions>(options, 'protoLoader') ||
GRPC_DEFAULT_PROTO_LOADER;
grpcPackage = this.loadPackage('grpc', ServerGrpc.name);
grpcProtoLoaderPackage = this.loadPackage(
protoLoader,
ServerGrpc.name,
);
grpcProtoLoaderPackage = this.loadPackage(protoLoader, ServerGrpc.name);
}
public async listen(callback: () => void) {
@@ -55,16 +60,30 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
this.logger.error(invalidPackageError.message, invalidPackageError.stack);
throw invalidPackageError;
}
for (const name of this.getServiceNames(grpcPkg)) {
// Take all of the services defined in grpcPkg and assign them to
// method handlers defined in Controllers
for (const definition of this.getServiceNames(grpcPkg)) {
this.grpcClient.addService(
grpcPkg[name].service,
await this.createService(grpcPkg[name], name),
// First parameter requires exact service definition from proto
definition.service.service,
// Here full proto definition required along with namespaced pattern name
await this.createService(definition.service, definition.name),
);
}
}
public getServiceNames(grpcPkg: any) {
return Object.keys(grpcPkg).filter(name => grpcPkg[name].service);
/**
* Will return all of the services along with their fully namespaced
* names as an array of objects.
* This method initiates recursive scan of grpcPkg object
*/
public getServiceNames(grpcPkg: any): { name: string; service: any }[] {
// Define accumulator to collect all of the services available to load
const services: { name: string; service: any }[] = [];
// Initiate recursive services collector starting with empty name
this.collectDeepServices('', grpcPkg, services);
return services;
}
public async createService(grpcService: any, name: string) {
@@ -137,7 +156,10 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
}
public createClient(): any {
const server = new grpcPackage.Server();
const server = new grpcPackage.Server({
'grpc.max_send_message_length': this.getOptionsProp<GrpcOptions>(this.options, 'maxSendMessageLength', GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH),
'grpc.max_receive_message_length': this.getOptionsProp<GrpcOptions>(this.options, 'maxReceiveMessageLength', GRPC_DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH)
});
const credentials = this.getOptionsProp<GrpcOptions>(
this.options,
'credentials',
@@ -177,4 +199,58 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
throw invalidProtoError;
}
}
/**
* Recursively fetch all of the service methods available on loaded
* protobuf descriptor object, and collect those as an objects with
* dot-syntax full-path names.
*
* Example:
* for proto package Bundle.FirstService with service Events { rpc...
* will be resolved to object of (while loaded for Bundle package):
* {
* name: "FirstService.Events",
* service: {Object}
* }
*/
private collectDeepServices(
name: string,
grpcDefinition: any,
accumulator: { name: string; service: any }[],
) {
if (!isObject(grpcDefinition)) {
return;
}
const keysToTraverse = Object.keys(grpcDefinition);
// Traverse definitions or namespace extensions
for (const key of keysToTraverse) {
const nameExtended = this.parseDeepServiceName(name, key);
const deepDefinition = grpcDefinition[key];
const isServiceDefined = !isUndefined(deepDefinition.service);
const isServiceBoolean = isServiceDefined
? deepDefinition.service !== false
: false;
if (isServiceDefined && isServiceBoolean) {
accumulator.push({
name: nameExtended,
service: deepDefinition,
});
}
// Continue recursion until objects end or service definition found
else {
this.collectDeepServices(nameExtended, deepDefinition, accumulator);
}
}
}
private parseDeepServiceName(name: string, key: string): string {
// If depth is zero then just return key
if (name.length === 0) {
return key;
}
// Otherwise add next through dot syntax
return name + '.' + key;
}
}

View File

@@ -63,7 +63,7 @@ export abstract class Server {
prop: keyof T['options'],
defaultValue = undefined,
) {
return obj ? obj[prop as string] : defaultValue;
return obj && obj[prop as string] || defaultValue;
}
protected handleError(error: string) {

View File

@@ -51,10 +51,16 @@ describe('ServerGrpc', () => {
});
describe('when package exist', () => {
it('should call "addService"', async () => {
const serviceNames = ['test', 'test2'];
const serviceNames = [{
name: 'test',
service: true
}, {
name: 'test2',
service: true
}];
sinon.stub(server, 'lookupPackage').callsFake(() => ({
test: true,
test2: true,
test: {service: true},
test2: {service: true}
}));
sinon.stub(server, 'getServiceNames').callsFake(() => serviceNames);
@@ -73,7 +79,16 @@ describe('ServerGrpc', () => {
key2: { service: true },
key3: { service: false },
};
const expected = ['key', 'key2'];
const expected = [
{
name: 'key',
service: {service: true}
},
{
name: 'key2',
service: {service: true}
}
];
expect(server.getServiceNames(obj)).to.be.eql(expected);
});
});
@@ -225,4 +240,57 @@ describe('ServerGrpc', () => {
expect(server.deserialize(content)).to.equal(content);
});
});
describe('proto interfaces parser should account for package namespaces', () => {
it('should parse multi-level proto package tree"', () => {
const grpcPkg = {
A: {
C: {
E: {
service: {
serviceName: {}
}
}
}
},
B: {
D: {
service: {
serviceName: {}
}
}
}
};
const svcs = server.getServiceNames(grpcPkg);
expect(svcs.length).to
.be.equal(
2,
'Amount of services collected from namespace should be equal 2'
);
expect(svcs[0].name).to.be.equal('A.C.E');
expect(svcs[1].name).to.be.equal('B.D');
});
it('should parse single level proto package tree"', () => {
const grpcPkg = {
A: {
service: {
serviceName: {}
}
},
B: {
service: {
serviceName: {}
}
}
};
const services = server.getServiceNames(grpcPkg);
expect(services.length).to
.be.equal(
2,
'Amount of services collected from namespace should be equal 2'
);
expect(services[0].name).to.be.equal('A');
expect(services[1].name).to.be.equal('B');
});
});
});

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

@@ -1,6 +1,6 @@
{
"name": "@nestjs/testing",
"version": "5.5.0",
"version": "5.6.2",
"description": "Nest - modern, fast, powerful node.js web framework (@testing)",
"author": "Kamil Mysliwiec",
"license": "MIT",

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

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

7457
yarn.lock

File diff suppressed because it is too large Load Diff