Compare commits

...

537 Commits

Author SHA1 Message Date
Kamil Myśliwiec
a96b08465e chore(@nestjs) publish v7.6.10 release 2021-02-03 09:27:25 +01:00
Kamil Myśliwiec
c47c45b6ff Merge branch 'master' of https://github.com/nestjs/nest 2021-02-03 09:24:24 +01:00
Kamil Myśliwiec
93b5598a33 fix(common): flatten nested errors (parse array pipe) 2021-02-03 09:24:14 +01:00
Kamil Mysliwiec
29497d61af Merge pull request #6298 from nestjs/renovate/ws-7.x
fix(deps): update dependency ws to v7.4.3
2021-02-03 09:19:54 +01:00
Renovate Bot
f37e23c5ea fix(deps): update dependency ws to v7.4.3 2021-02-03 07:57:40 +00:00
Kamil Mysliwiec
fa0e011b03 Merge pull request #6299 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.20.0
2021-02-03 08:55:06 +01:00
Kamil Mysliwiec
d034e62ff0 Merge pull request #6301 from nestjs/renovate/mongodb-3.x
fix(deps): update dependency mongodb to v3.6.4
2021-02-03 08:55:01 +01:00
Kamil Mysliwiec
396fe779e6 Merge pull request #6302 from nestjs/renovate/babel-monorepo
chore(deps): update babel monorepo to v7.12.13
2021-02-03 08:54:56 +01:00
Kamil Mysliwiec
5728578e10 Merge pull request #6304 from nestjs/dependabot/npm_and_yarn/ws-7.4.3
chore(deps): bump ws from 7.4.2 to 7.4.3
2021-02-03 08:52:02 +01:00
dependabot[bot]
0db1b041ef chore(deps): bump ws from 7.4.2 to 7.4.3
Bumps [ws](https://github.com/websockets/ws) from 7.4.2 to 7.4.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.2...7.4.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-03 05:12:10 +00:00
Renovate Bot
821574cee9 chore(deps): update babel monorepo to v7.12.13 2021-02-03 02:41:11 +00:00
Renovate Bot
90d64d085d fix(deps): update dependency mongodb to v3.6.4 2021-02-02 22:55:57 +00:00
Renovate Bot
6db30813de chore(deps): update dependency webpack to v5.20.0 2021-02-02 21:19:16 +00:00
Kamil Mysliwiec
b336fd172c Merge pull request #6295 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.9
2021-02-02 13:43:50 +01:00
Renovate Bot
3123ad3f19 fix(deps): update nest monorepo to v7.6.9 2021-02-02 12:35:09 +00:00
Kamil Mysliwiec
fc5f3c91af Merge pull request #6293 from nestjs/renovate/engine.io-client-4.x
chore(deps): update dependency engine.io-client to v4.1.1
2021-02-02 12:41:19 +01:00
Kamil Myśliwiec
e51ab047d2 chore(@nestjs) publish v7.6.9 release 2021-02-02 11:24:11 +01:00
Kamil Myśliwiec
2ba2b99325 fix(common): validate all array items when stop at first disabled (#6263) 2021-02-02 11:12:45 +01:00
Kamil Myśliwiec
ba37eee5b0 Merge branch 'andrewda-host-array' 2021-02-02 10:35:50 +01:00
Kamil Myśliwiec
4804f32472 refactor(core): tweaks to host filtering, extract error message 2021-02-02 10:35:26 +01:00
Kamil Myśliwiec
40a0678fbf Merge branch 'host-array' of https://github.com/andrewda/nest into andrewda-host-array 2021-02-02 10:28:56 +01:00
Renovate Bot
a11d167130 chore(deps): update dependency engine.io-client to v4.1.1 2021-02-02 09:25:49 +00:00
Kamil Mysliwiec
6b119c3579 Merge pull request #6289 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.14.2
2021-02-02 08:41:55 +01:00
Renovate Bot
f22d3370f3 chore(deps): update typescript-eslint monorepo to v4.14.2 2021-02-01 20:22:34 +00:00
Kamil Mysliwiec
c12100c3c6 Merge pull request #6288 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.8
2021-02-01 16:12:27 +01:00
Renovate Bot
8cf29c9172 fix(deps): update nest monorepo to v7.6.8 2021-02-01 14:42:54 +00:00
Kamil Myśliwiec
12ac1108a7 chore(): bump package json version 2021-02-01 15:26:40 +01:00
Kamil Myśliwiec
c150deefbd chore(@nestjs) publish v7.6.8 release 2021-02-01 15:25:38 +01:00
Kamil Myśliwiec
68b5d2a8e2 chore(): update README 2021-02-01 15:23:44 +01:00
Kamil Mysliwiec
4d87dd6b1e Merge pull request #6287 from nestjs/renovate/imports-loader-2.x
chore(deps): update dependency imports-loader to v2
2021-02-01 14:27:23 +01:00
Kamil Myśliwiec
e0b825121b Merge branch 'jmcdo29-feat/microservice-deserialize-error' 2021-02-01 14:26:37 +01:00
Kamil Myśliwiec
dc8b1d5c72 refactor(microservices): rename is custom client options method 2021-02-01 14:23:37 +01:00
Renovate Bot
832b3bc90c chore(deps): update dependency imports-loader to v2 2021-02-01 13:20:14 +00:00
Kamil Myśliwiec
8180e5905c Merge branch 'feat/microservice-deserialize-error' of https://github.com/jmcdo29/nest into jmcdo29-feat/microservice-deserialize-error 2021-02-01 13:46:55 +01:00
Kamil Myśliwiec
2307373bfe Merge branch 'gabeodess-graphql-schema-first-resolve-field' 2021-02-01 13:44:50 +01:00
Kamil Myśliwiec
71255392c9 sample(12-graphql-schema-first): fix sample 2021-02-01 13:43:45 +01:00
Kamil Myśliwiec
07c8cdc80b Merge branch 'graphql-schema-first-resolve-field' of https://github.com/gabeodess/nest into gabeodess-graphql-schema-first-resolve-field 2021-02-01 13:18:56 +01:00
Kamil Mysliwiec
f9e5272e2b Merge pull request #6286 from nestjs/renovate/point-of-view-4.x
fix(deps): update dependency point-of-view to v4.11.0
2021-02-01 13:14:06 +01:00
Renovate Bot
b842a7e817 fix(deps): update dependency point-of-view to v4.11.0 2021-02-01 12:12:15 +00:00
Kamil Mysliwiec
8df890a8ac Merge pull request #6245 from bonkboykz/fix-websockets-metadata-typings
fix(websockets): fix typings for gatewaymetadata origins
2021-02-01 13:10:34 +01:00
Kamil Mysliwiec
060befe22e Merge pull request #6257 from Tony133/chore/update-transform-options
chore(): update interface for transform options
2021-02-01 13:10:23 +01:00
Kamil Mysliwiec
06bddccb5c Merge pull request #6249 from nestjs/renovate/point-of-view-4.x
fix(deps): update dependency point-of-view to v4.10.0
2021-02-01 13:08:39 +01:00
Kamil Mysliwiec
4f88c3d147 Merge pull request #6282 from nestjs/renovate/eslint-7.x
chore(deps): update dependency eslint to v7.19.0
2021-02-01 10:00:30 +01:00
Renovate Bot
dd7c176df3 fix(deps): update dependency point-of-view to v4.10.0 2021-02-01 07:56:45 +00:00
Renovate Bot
c43fb62322 chore(deps): update dependency eslint to v7.19.0 2021-02-01 07:53:50 +00:00
Kamil Mysliwiec
8c4fb929b7 Merge pull request #6276 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.19.0
2021-02-01 08:38:52 +01:00
Kamil Mysliwiec
1130edc150 Merge pull request #6285 from nestjs/dependabot/npm_and_yarn/point-of-view-4.10.0
chore(deps-dev): bump point-of-view from 4.9.0 to 4.10.0
2021-02-01 08:38:34 +01:00
dependabot[bot]
6417c5477a chore(deps-dev): bump point-of-view from 4.9.0 to 4.10.0
Bumps [point-of-view](https://github.com/fastify/point-of-view) from 4.9.0 to 4.10.0.
- [Release notes](https://github.com/fastify/point-of-view/releases)
- [Commits](https://github.com/fastify/point-of-view/compare/v4.9.0...v4.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:49:52 +00:00
Kamil Mysliwiec
149483a852 Update Readme.md 2021-01-30 12:41:17 +01:00
Kamil Mysliwiec
27d9202108 Update readme_jp.md 2021-01-30 12:33:13 +01:00
Kamil Mysliwiec
950e3697c7 Merge pull request #6275 from pochi-sato/master
docs(readme): Create Readme for "Japanese"!
2021-01-30 11:57:09 +01:00
Renovate Bot
df5a7c3a48 chore(deps): update dependency webpack to v5.19.0 2021-01-30 10:25:03 +00:00
Kamil Mysliwiec
25b7ad5805 Merge pull request #6273 from nestjs/renovate/ts-jest-26.x
chore(deps): update dependency ts-jest to v26.5.0
2021-01-30 11:23:19 +01:00
Takuto Sato
0f668075fb Create Readme for "Japanese"! 2021-01-30 00:45:31 +09:00
Renovate Bot
b74f80fb1c chore(deps): update dependency ts-jest to v26.5.0 2021-01-29 14:36:13 +00:00
Kamil Mysliwiec
a0d08f049c Merge pull request #6268 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.14
2021-01-29 13:47:55 +01:00
Renovate Bot
c88db600a0 fix(deps): update dependency mongoose to v5.11.14 2021-01-29 10:44:03 +00:00
Kamil Mysliwiec
e196f51608 Update Readme.md 2021-01-28 11:56:17 +01:00
Kamil Mysliwiec
f4c45f8d88 Update Readme.md 2021-01-28 11:54:50 +01:00
Tony133
4baea48cfa chore(): update interface for trasform options ref:6256 2021-01-27 15:36:18 +01:00
Kamil Mysliwiec
275e71f89a Merge pull request #6231 from nestjs/renovate/supertest-6.x
chore(deps): update dependency supertest to v6.1.3
2021-01-27 10:41:35 +01:00
Kamil Mysliwiec
4a1074a793 Merge pull request #6255 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.7
2021-01-27 10:33:15 +01:00
Kamil Mysliwiec
e9d1735688 Merge pull request #6250 from nestjs/renovate/sequelize-6.x
fix(deps): update dependency sequelize to v6.5.0
2021-01-27 10:31:12 +01:00
Kamil Mysliwiec
3b93861706 Merge pull request #6251 from nestjs/dependabot/npm_and_yarn/point-of-view-4.9.0
chore(deps-dev): bump point-of-view from 4.8.0 to 4.9.0
2021-01-27 10:31:05 +01:00
Renovate Bot
6d1c02be01 fix(deps): update nest monorepo to v7.6.7 2021-01-27 09:23:22 +00:00
Kamil Myśliwiec
1e5f60ed17 chore(@nestjs) publish v7.6.7 release 2021-01-27 09:32:28 +01:00
Kamil Myśliwiec
6379162871 Merge branch 'master' of https://github.com/nestjs/nest 2021-01-27 09:06:37 +01:00
Kamil Myśliwiec
fddc980b1d fix(common): fallback to the default get timestamp fn (logger) 2021-01-27 09:06:28 +01:00
Renovate Bot
6027001b4e fix(deps): update dependency sequelize to v6.5.0 2021-01-27 07:37:18 +00:00
dependabot[bot]
0cd83570a2 chore(deps-dev): bump point-of-view from 4.8.0 to 4.9.0
Bumps [point-of-view](https://github.com/fastify/point-of-view) from 4.8.0 to 4.9.0.
- [Release notes](https://github.com/fastify/point-of-view/releases)
- [Commits](https://github.com/fastify/point-of-view/compare/v4.8.0...v4.9.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-27 07:33:14 +00:00
Kamil Mysliwiec
48d91c9646 Merge pull request #6252 from nestjs/dependabot/npm_and_yarn/graphql-15.5.0
chore(deps-dev): bump graphql from 15.4.0 to 15.5.0
2021-01-27 08:30:44 +01:00
Kamil Mysliwiec
9b9b3564a4 Merge pull request #6247 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.18.0
2021-01-27 08:30:30 +01:00
dependabot[bot]
25526070a1 chore(deps-dev): bump graphql from 15.4.0 to 15.5.0
Bumps [graphql](https://github.com/graphql/graphql-js) from 15.4.0 to 15.5.0.
- [Release notes](https://github.com/graphql/graphql-js/releases)
- [Commits](https://github.com/graphql/graphql-js/compare/v15.4.0...v15.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-27 05:26:26 +00:00
Renovate Bot
6df1712b0d chore(deps): update dependency webpack to v5.18.0 2021-01-26 20:59:38 +00:00
Renovate Bot
8aa0f75c8c chore(deps): update dependency supertest to v6.1.3 2021-01-26 10:43:58 +00:00
Kamil Mysliwiec
c0babd6cfd Merge pull request #6238 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.14.1
2021-01-26 11:29:45 +01:00
Kamil Mysliwiec
6448d17f43 Merge pull request #6239 from nestjs/renovate/socket.io-2.x
chore(deps): update dependency @types/socket.io to v2.1.13
2021-01-26 11:29:21 +01:00
Kamil Mysliwiec
6a9c9100f5 Merge pull request #6241 from nestjs/dependabot/npm_and_yarn/supertest-6.1.3
chore(deps-dev): bump supertest from 6.1.1 to 6.1.3
2021-01-26 11:29:13 +01:00
Renovate Bot
55c7051787 chore(deps): update typescript-eslint monorepo to v4.14.1 2021-01-26 09:44:24 +00:00
Renovate Bot
db6a555d29 chore(deps): update dependency @types/socket.io to v2.1.13 2021-01-26 09:16:01 +00:00
dependabot[bot]
7c722c3d0b chore(deps-dev): bump supertest from 6.1.1 to 6.1.3
Bumps [supertest](https://github.com/visionmedia/supertest) from 6.1.1 to 6.1.3.
- [Release notes](https://github.com/visionmedia/supertest/releases)
- [Commits](https://github.com/visionmedia/supertest/compare/v6.1.1...v6.1.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-26 08:58:14 +00:00
Kamil Mysliwiec
e7011e3b4f Merge pull request #6244 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.6
2021-01-26 09:55:53 +01:00
Yesset Zhussupov
0fb8e1a025 fix(websockets): fix typings for gatewaymetadata origins 2021-01-26 14:04:12 +06:00
Renovate Bot
459458bbb4 fix(deps): update nest monorepo to v7.6.6 2021-01-26 07:54:06 +00:00
Kamil Myśliwiec
9e96e76e1a chore(@nestjs) publish v7.6.6 release 2021-01-26 08:37:47 +01:00
Kamil Myśliwiec
a63db1b8aa fix(common): check if error is a plain object (logger) 2021-01-26 08:29:35 +01:00
Kamil Myśliwiec
477b6d0d5c Merge branch 'Sikora00-6118' 2021-01-26 08:26:01 +01:00
Kamil Myśliwiec
90aa625bf8 fix(): fix relative imports 2021-01-26 08:25:46 +01:00
Kamil Myśliwiec
e8541185f0 Merge branch '6118' of https://github.com/Sikora00/nest into Sikora00-6118 2021-01-26 08:12:18 +01:00
Kamil Myśliwiec
c48e2bcfdb fix(common): check if get timestamp is present on logger 2021-01-26 08:10:03 +01:00
Kamil Mysliwiec
667df81eb5 Merge pull request #6243 from nestjs/dependabot/npm_and_yarn/types/socket.io-2.1.13
chore(deps-dev): bump @types/socket.io from 2.1.12 to 2.1.13
2021-01-26 08:07:45 +01:00
dependabot[bot]
fb5117c241 chore(deps-dev): bump @types/socket.io from 2.1.12 to 2.1.13
Bumps [@types/socket.io](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/socket.io) from 2.1.12 to 2.1.13.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/socket.io)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-26 05:28:18 +00:00
Maciej Sikorski
ec9727093d feat: allow to config cors async
Bump version of the fastify-cors.
Add CorsOptionsDelegate interface.
Add CorsOptionsDelegate as an acceptable type
for every enableCors usage.

Closes nestjs/nest#6118
2021-01-25 22:46:11 +01:00
Kamil Mysliwiec
d2e6616115 Merge pull request #6235 from nestjs/renovate/fastify-3.x
fix(deps): update dependency fastify to v3.11.0
2021-01-25 13:02:16 +01:00
Renovate Bot
9f3614042f fix(deps): update dependency fastify to v3.11.0 2021-01-25 10:32:31 +00:00
Kamil Mysliwiec
2bc2c8adfa Merge pull request #6148 from nestjs/renovate/class-transformer-0.x
fix(deps): update dependency class-transformer to v0.3.2
2021-01-25 11:26:27 +01:00
Kamil Mysliwiec
e4c5d17df2 Merge pull request #6233 from nestjs/renovate/fastify-cors-5.x
fix(deps): update dependency fastify-cors to v5.2.0
2021-01-25 11:13:09 +01:00
Kamil Mysliwiec
bf420cd91d Merge pull request #6226 from nestjs/renovate/sinon-9.x
chore(deps): update dependency sinon to v9.2.4
2021-01-25 11:12:44 +01:00
Renovate Bot
5d48691713 fix(deps): update dependency class-transformer to v0.3.2 2021-01-25 09:08:37 +00:00
Kamil Myśliwiec
454d519c67 sample(21-serializer): fix transform decorator usage 2021-01-25 09:57:35 +01:00
Renovate Bot
60f256ecdf chore(deps): update dependency sinon to v9.2.4 2021-01-25 08:33:25 +00:00
Renovate Bot
df4c2eb318 fix(deps): update dependency fastify-cors to v5.2.0 2021-01-25 08:30:00 +00:00
Kamil Mysliwiec
843116eea9 Merge pull request #6124 from nestjs/renovate/class-validator-0.x
fix(deps): update dependency class-validator to v0.13.1
2021-01-25 09:26:37 +01:00
Kamil Mysliwiec
3af5404401 Merge pull request #6224 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.8
2021-01-25 09:25:55 +01:00
Kamil Mysliwiec
9a6610cb07 Merge pull request #6202 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.22
2021-01-25 09:25:44 +01:00
Kamil Mysliwiec
a76a6e4a30 Merge pull request #6230 from nestjs/dependabot/npm_and_yarn/nestjs/graphql-7.9.8
chore(deps-dev): bump @nestjs/graphql from 7.9.7 to 7.9.8
2021-01-25 09:21:16 +01:00
Renovate Bot
d063c4772d fix(deps): update dependency @nestjs/graphql to v7.9.8 2021-01-25 08:20:24 +00:00
Renovate Bot
64d78a9c80 chore(deps): update dependency @types/node to v14.14.22 2021-01-25 07:59:35 +00:00
Kamil Mysliwiec
efe4884c27 Merge pull request #6188 from nestjs/renovate/eslint-config-prettier-7.x
chore(deps): update dependency eslint-config-prettier to v7.2.0
2021-01-25 08:48:17 +01:00
Kamil Mysliwiec
5ebd3353b1 Merge pull request #6222 from nestjs/renovate/nestjs-schematics-7.x
chore(deps): update dependency @nestjs/schematics to v7.2.7
2021-01-25 08:47:58 +01:00
Kamil Mysliwiec
5d2fa36556 Merge pull request #6223 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.17.0
2021-01-25 08:47:51 +01:00
Kamil Mysliwiec
1440ccaa4b Merge pull request #6225 from nestjs/renovate/nestjs-schedule-0.x
fix(deps): update dependency @nestjs/schedule to v0.4.2
2021-01-25 08:47:41 +01:00
Kamil Mysliwiec
42262df197 Merge pull request #6229 from nestjs/dependabot/npm_and_yarn/class-validator-0.13.1
chore(deps): bump class-validator from 0.12.2 to 0.13.1
2021-01-25 08:47:29 +01:00
dependabot[bot]
6f119c843c chore(deps-dev): bump @nestjs/graphql from 7.9.7 to 7.9.8
Bumps [@nestjs/graphql](https://github.com/nestjs/graphql) from 7.9.7 to 7.9.8.
- [Release notes](https://github.com/nestjs/graphql/releases)
- [Changelog](https://github.com/nestjs/graphql/blob/master/.release-it.json)
- [Commits](https://github.com/nestjs/graphql/compare/7.9.7...7.9.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:38:54 +00:00
dependabot[bot]
cb0564d77a chore(deps): bump class-validator from 0.12.2 to 0.13.1
Bumps [class-validator](https://github.com/typestack/class-validator) from 0.12.2 to 0.13.1.
- [Release notes](https://github.com/typestack/class-validator/releases)
- [Changelog](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/typestack/class-validator/compare/v0.12.2...v0.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:36:01 +00:00
Renovate Bot
d28c25618d fix(deps): update dependency class-validator to v0.13.1 2021-01-22 15:21:18 +00:00
Renovate Bot
4a57915f5a fix(deps): update dependency @nestjs/schedule to v0.4.2 2021-01-22 14:58:33 +00:00
Renovate Bot
3188b801bd chore(deps): update dependency webpack to v5.17.0 2021-01-22 14:54:06 +00:00
Renovate Bot
b7e46f45d4 chore(deps): update dependency eslint-config-prettier to v7.2.0 2021-01-22 14:53:19 +00:00
Renovate Bot
993e5f4a91 chore(deps): update dependency @nestjs/schematics to v7.2.7 2021-01-22 14:27:35 +00:00
Kamil Myśliwiec
bc394eabb2 sample(07-sequelize): fix sample 2021-01-22 15:13:00 +01:00
Kamil Mysliwiec
0b874e7dfc Merge pull request #6220 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.7
2021-01-22 13:07:39 +01:00
Renovate Bot
a65fcd1472 fix(deps): update dependency @nestjs/graphql to v7.9.7 2021-01-22 10:55:03 +00:00
Kamil Mysliwiec
159cdce1f1 Merge pull request #6214 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.6
2021-01-22 09:51:17 +01:00
Kamil Mysliwiec
b298b8bc92 Merge pull request #6215 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.12
2021-01-22 09:49:39 +01:00
Renovate Bot
53226211f7 fix(deps): update dependency @nestjs/graphql to v7.9.6 2021-01-22 08:42:36 +00:00
Kamil Mysliwiec
d4bb87c5eb Merge pull request #6208 from nestjs/renovate/grpc-proto-loader-0.x
fix(deps): update dependency @grpc/proto-loader to v0.5.6
2021-01-22 09:39:39 +01:00
Kamil Mysliwiec
fa4642f70f Merge pull request #6218 from nestjs/dependabot/npm_and_yarn/nestjs/graphql-7.9.6
chore(deps-dev): bump @nestjs/graphql from 7.9.5 to 7.9.6
2021-01-22 09:39:12 +01:00
dependabot[bot]
c4c1b7c6a5 chore(deps-dev): bump @nestjs/graphql from 7.9.5 to 7.9.6
Bumps [@nestjs/graphql](https://github.com/nestjs/graphql) from 7.9.5 to 7.9.6.
- [Release notes](https://github.com/nestjs/graphql/releases)
- [Changelog](https://github.com/nestjs/graphql/blob/master/.release-it.json)
- [Commits](https://github.com/nestjs/graphql/compare/7.9.5...7.9.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-22 05:25:16 +00:00
Renovate Bot
2be4c4cd70 fix(deps): update dependency @nestjs/swagger to v4.7.12 2021-01-21 14:26:02 +00:00
Renovate Bot
76289893d7 fix(deps): update dependency @grpc/proto-loader to v0.5.6 2021-01-21 14:07:44 +00:00
Kamil Mysliwiec
b3e654e84d Merge pull request #6209 from nestjs/dependabot/npm_and_yarn/types/cache-manager-3.4.0
chore(deps-dev): bump @types/cache-manager from 2.10.3 to 3.4.0
2021-01-21 10:05:56 +01:00
Kamil Mysliwiec
668d781b6c Merge pull request #6206 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.13
2021-01-21 10:05:48 +01:00
Kamil Mysliwiec
fb45437621 Merge pull request #6211 from nestjs/dependabot/npm_and_yarn/mongoose-5.11.13
chore(deps-dev): bump mongoose from 5.11.12 to 5.11.13
2021-01-21 09:23:15 +01:00
dependabot[bot]
0c7bf92086 chore(deps-dev): bump @types/cache-manager from 2.10.3 to 3.4.0
Bumps [@types/cache-manager](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/cache-manager) from 2.10.3 to 3.4.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/cache-manager)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-21 08:15:13 +00:00
dependabot[bot]
091d09fde2 chore(deps-dev): bump mongoose from 5.11.12 to 5.11.13
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.11.12 to 5.11.13.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.11.12...5.11.13)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-21 08:14:29 +00:00
Kamil Mysliwiec
653f0a4281 Merge pull request #6210 from nestjs/dependabot/npm_and_yarn/grpc/proto-loader-0.5.6
chore(deps-dev): bump @grpc/proto-loader from 0.5.5 to 0.5.6
2021-01-21 09:09:52 +01:00
dependabot[bot]
48d899d025 chore(deps-dev): bump @grpc/proto-loader from 0.5.5 to 0.5.6
Bumps [@grpc/proto-loader](https://github.com/grpc/grpc-node) from 0.5.5 to 0.5.6.
- [Release notes](https://github.com/grpc/grpc-node/releases)
- [Commits](https://github.com/grpc/grpc-node/commits/@grpc/proto-loader@0.5.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-21 08:08:22 +00:00
Renovate Bot
81f3161f7c fix(deps): update dependency mongoose to v5.11.13 2021-01-21 08:06:47 +00:00
Kamil Mysliwiec
0f29446c65 Merge pull request #6194 from nestjs/dependabot/npm_and_yarn/eslint-config-prettier-7.2.0
chore(deps-dev): bump eslint-config-prettier from 7.1.0 to 7.2.0
2021-01-21 09:01:06 +01:00
Kamil Mysliwiec
1b31a744a8 Merge pull request #6199 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.16.0
2021-01-20 11:02:36 +01:00
Renovate Bot
0fe31b9bc8 chore(deps): update dependency webpack to v5.16.0 2021-01-20 07:31:32 +00:00
dependabot[bot]
5da5a4ad58 chore(deps-dev): bump eslint-config-prettier from 7.1.0 to 7.2.0
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v7.1.0...v7.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-20 07:07:48 +00:00
Kamil Mysliwiec
2abb9b2154 Merge pull request #6203 from nestjs/dependabot/npm_and_yarn/types/node-14.14.22
chore(deps-dev): bump @types/node from 14.14.21 to 14.14.22
2021-01-20 08:03:38 +01:00
Kamil Mysliwiec
43f053ab21 Merge pull request #6196 from nestjs/renovate/webpack-cli-4.x
chore(deps): update dependency webpack-cli to v4.4.0
2021-01-20 08:03:04 +01:00
Kamil Mysliwiec
a74725d585 Merge pull request #6192 from nestjs/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.14.0
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.13.0 to 4.14.0
2021-01-20 08:00:38 +01:00
Kamil Mysliwiec
51f5de8333 Merge pull request #6186 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.14.0
2021-01-20 07:59:58 +01:00
Kamil Mysliwiec
0c8b004bf9 Merge pull request #6204 from nestjs/dependabot/npm_and_yarn/core-js-3.8.3
chore(deps-dev): bump core-js from 3.8.2 to 3.8.3
2021-01-20 07:59:24 +01:00
dependabot[bot]
3ce92c7883 chore(deps-dev): bump core-js from 3.8.2 to 3.8.3
Bumps [core-js](https://github.com/zloirock/core-js) from 3.8.2 to 3.8.3.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.8.2...v3.8.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-20 05:17:17 +00:00
dependabot[bot]
3bbde4c26c chore(deps-dev): bump @types/node from 14.14.21 to 14.14.22
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.21 to 14.14.22.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-20 05:14:40 +00:00
Renovate Bot
a48107ef92 chore(deps): update dependency webpack-cli to v4.4.0 2021-01-19 13:29:00 +00:00
Renovate Bot
b7990aa5b1 chore(deps): update typescript-eslint monorepo to v4.14.0 2021-01-19 08:35:09 +00:00
dependabot[bot]
07737aa371 chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.13.0 to 4.14.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.14.0/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-19 08:08:17 +00:00
Kamil Mysliwiec
ca7b79532f Merge pull request #6163 from nestjs/dependabot/npm_and_yarn/class-transformer-0.3.2
chore(deps): bump class-transformer from 0.3.1 to 0.3.2
2021-01-19 09:05:26 +01:00
Kamil Mysliwiec
ad6ce62f0e Merge pull request #6187 from nestjs/renovate/bull-3.x
chore(deps): update dependency @types/bull to v3.15.0
2021-01-19 09:04:07 +01:00
Kamil Mysliwiec
4c814a2d85 Merge pull request #6190 from nestjs/renovate/docker-mysql-5.x
chore(deps): update mysql docker tag to v5.7.33
2021-01-19 09:04:00 +01:00
Kamil Mysliwiec
1dbb8ff3db Merge pull request #6189 from nestjs/renovate/sequelize-6.x
fix(deps): update dependency sequelize to v6.4.0
2021-01-19 09:03:49 +01:00
Kamil Mysliwiec
c6780a3a91 Merge pull request #6193 from nestjs/dependabot/npm_and_yarn/typescript-eslint/parser-4.14.0
chore(deps-dev): bump @typescript-eslint/parser from 4.13.0 to 4.14.0
2021-01-19 09:03:30 +01:00
dependabot[bot]
1945f8d24a chore(deps-dev): bump @typescript-eslint/parser from 4.13.0 to 4.14.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.13.0 to 4.14.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.14.0/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-19 05:24:49 +00:00
Renovate Bot
ccd4fdae58 chore(deps): update mysql docker tag to v5.7.33 2021-01-19 00:01:32 +00:00
Renovate Bot
817d9f45e0 fix(deps): update dependency sequelize to v6.4.0 2021-01-18 20:51:31 +00:00
Renovate Bot
9362db8042 chore(deps): update dependency @types/bull to v3.15.0 2021-01-18 20:37:09 +00:00
dependabot[bot]
2fb5f4dd16 chore(deps): bump class-transformer from 0.3.1 to 0.3.2
Bumps [class-transformer](https://github.com/typestack/class-transformer) from 0.3.1 to 0.3.2.
- [Release notes](https://github.com/typestack/class-transformer/releases)
- [Changelog](https://github.com/typestack/class-transformer/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/typestack/class-transformer/compare/v0.3.1...v0.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 08:52:25 +00:00
Kamil Mysliwiec
a400be366b Merge pull request #6176 from nestjs/renovate/eslint-7.x
chore(deps): update dependency eslint to v7.18.0
2021-01-18 09:20:54 +01:00
Renovate Bot
7267409d91 chore(deps): update dependency eslint to v7.18.0 2021-01-17 11:51:47 +00:00
Kamil Mysliwiec
fa494041c8 Merge pull request #6167 from nestjs/renovate/fastify-3.x
fix(deps): update dependency fastify to v3.10.1
2021-01-17 12:31:14 +01:00
Kamil Mysliwiec
af4f041d6a Merge pull request #6168 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.11
2021-01-17 12:23:18 +01:00
Kamil Mysliwiec
562b2bb175 Merge pull request #6170 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.5
2021-01-17 12:23:10 +01:00
Kamil Mysliwiec
36c2a35614 Merge pull request #6171 from nestjs/renovate/supertest-6.x
chore(deps): update dependency supertest to v6.1.1
2021-01-17 12:23:02 +01:00
Kamil Mysliwiec
fb4cc36c75 Merge pull request #6173 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.15.0
2021-01-17 12:22:57 +01:00
Kamil Mysliwiec
7386204da6 Merge pull request #6177 from nestjs/renovate/husky-4.x
chore(deps): update dependency husky to v4.3.8
2021-01-17 12:22:41 +01:00
Renovate Bot
d99370bb1d chore(deps): update dependency husky to v4.3.8 2021-01-16 00:53:14 +00:00
Renovate Bot
90fcd3599e chore(deps): update dependency supertest to v6.1.1 2021-01-15 19:20:48 +00:00
Renovate Bot
e3a66d1902 chore(deps): update dependency webpack to v5.15.0 2021-01-15 17:28:52 +00:00
Renovate Bot
71cab143e6 fix(deps): update dependency @nestjs/graphql to v7.9.5 2021-01-15 15:03:53 +00:00
Renovate Bot
3357fe0349 fix(deps): update dependency @nestjs/swagger to v4.7.11 2021-01-15 13:30:55 +00:00
Kamil Mysliwiec
be0cdfe7e6 Merge pull request #6165 from nestjs/renovate/fast-json-stringify-2.x
fix(deps): update dependency fast-json-stringify to v2.4.1
2021-01-15 13:10:11 +01:00
Renovate Bot
c9c92b47de fix(deps): update dependency fastify to v3.10.1 2021-01-15 12:09:31 +00:00
Kamil Mysliwiec
6fb25e93e2 Merge pull request #6155 from nestjs/renovate/apollo-graphql-packages
fix(deps): update apollo graphql packages to v2.19.2
2021-01-15 13:06:04 +01:00
Kamil Mysliwiec
6957b52afe Merge pull request #6156 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.21
2021-01-15 13:05:54 +01:00
Kamil Mysliwiec
5b7eae83e0 Merge pull request #6166 from nestjs/renovate/fastify-3.x
fix(deps): update dependency fastify to v3.10.0
2021-01-15 13:05:33 +01:00
Renovate Bot
52546cc62e fix(deps): update dependency fastify to v3.10.0 2021-01-15 10:36:34 +00:00
Renovate Bot
d43c4d7510 fix(deps): update dependency fast-json-stringify to v2.4.1 2021-01-15 10:01:20 +00:00
Kamil Mysliwiec
b4c24cc17e Merge pull request #6157 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.12
2021-01-15 09:12:01 +01:00
Renovate Bot
119190ad75 fix(deps): update dependency mongoose to v5.11.12 2021-01-14 22:32:03 +00:00
Renovate Bot
3361cfd236 chore(deps): update dependency @types/node to v14.14.21 2021-01-14 22:28:52 +00:00
Renovate Bot
0cf4409869 fix(deps): update apollo graphql packages to v2.19.2 2021-01-14 17:24:06 +00:00
Kamil Mysliwiec
5028393d57 Merge pull request #6154 from nestjs/renovate/fastify-static-3.x
fix(deps): update dependency fastify-static to v3.4.0
2021-01-14 16:07:35 +01:00
Renovate Bot
05b771a9c2 fix(deps): update dependency fastify-static to v3.4.0 2021-01-14 14:09:48 +00:00
Kamil Mysliwiec
d972d9ad8f Merge pull request #6150 from nestjs/renovate/nestjs-mongoose-7.x
fix(deps): update dependency @nestjs/mongoose to v7.2.2
2021-01-14 11:03:51 +01:00
Renovate Bot
668968faa9 fix(deps): update dependency @nestjs/mongoose to v7.2.2 2021-01-14 09:38:03 +00:00
Kamil Mysliwiec
d588b8bc68 Merge pull request #6147 from nestjs/dependabot/npm_and_yarn/engine.io-client-4.1.0
chore(deps-dev): bump engine.io-client from 4.0.6 to 4.1.0
2021-01-14 09:07:28 +01:00
Kamil Mysliwiec
1a0922a58b Merge pull request #6145 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.14.0
2021-01-14 08:38:14 +01:00
dependabot[bot]
cd04a8d58a chore(deps-dev): bump engine.io-client from 4.0.6 to 4.1.0
Bumps [engine.io-client](https://github.com/socketio/engine.io-client) from 4.0.6 to 4.1.0.
- [Release notes](https://github.com/socketio/engine.io-client/releases)
- [Changelog](https://github.com/socketio/engine.io-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io-client/compare/4.0.6...4.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-14 05:23:02 +00:00
Renovate Bot
ff935dac06 chore(deps): update dependency webpack to v5.14.0 2021-01-14 00:36:43 +00:00
Kamil Myśliwiec
ba2f5ae63a chore(): update LICENSE file 2021-01-13 13:25:04 +01:00
Kamil Mysliwiec
0d67f823d5 Merge pull request #6071 from nvdnkpr/master
feat(testing): adds builder method for optional custom logger
2021-01-13 12:48:56 +01:00
Kamil Mysliwiec
f001a9ab83 Merge pull request #5994 from sztadii/chore/linter-fix
chore: Run linter without --fix on CI
2021-01-13 11:48:21 +01:00
Kamil Myśliwiec
8bc4e92d21 Merge branch 'nean-update-class-validator' 2021-01-13 11:45:10 +01:00
Kamil Myśliwiec
d2d951870c docs(common): fix jsdoc comment 2021-01-13 11:44:55 +01:00
Kamil Myśliwiec
29e158ac66 Merge branch 'update-class-validator' of https://github.com/nean/nest into nean-update-class-validator 2021-01-13 11:35:50 +01:00
Kamil Mysliwiec
29192b38e4 Merge pull request #6062 from Tony133/chore/microservice-nats-options
chore(microservice): updated nats options
2021-01-13 11:30:58 +01:00
Kamil Mysliwiec
e6e11b9cf1 Update packages/testing/testing-module.builder.ts 2021-01-13 11:30:44 +01:00
Kamil Mysliwiec
38974dc290 Merge pull request #6082 from WonderPanda/feat/types-for-microservices-custom-strategy
fix(microservices): custom strategy typings
2021-01-13 11:30:12 +01:00
Kamil Mysliwiec
8b86d836c3 Merge pull request #6126 from nestjs/renovate/express-4.x
chore(deps): update dependency @types/express to v4.17.11
2021-01-13 10:55:33 +01:00
Renovate Bot
967206ca5d chore(deps): update dependency @types/express to v4.17.11 2021-01-13 09:00:21 +00:00
Kamil Mysliwiec
ca830a8519 Merge pull request #6139 from nestjs/dependabot/npm_and_yarn/types/express-4.17.11
chore(deps-dev): bump @types/express from 4.17.9 to 4.17.11
2021-01-13 09:48:12 +01:00
dependabot[bot]
ce28bee865 chore(deps-dev): bump @types/express from 4.17.9 to 4.17.11
Bumps [@types/express](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express) from 4.17.9 to 4.17.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-13 05:25:37 +00:00
Kamil Mysliwiec
9e20b0a858 Merge pull request #6135 from nestjs/renovate/typeorm-0.x
fix(deps): update dependency typeorm to v0.2.30
2021-01-12 17:00:16 +01:00
Renovate Bot
b60691737f fix(deps): update dependency typeorm to v0.2.30 2021-01-12 13:38:50 +00:00
Kamil Mysliwiec
41415b5b91 Merge pull request #6127 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.13.0
2021-01-12 11:56:31 +01:00
Kamil Mysliwiec
65d2fac038 Merge pull request #6132 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.10
2021-01-12 11:56:21 +01:00
Renovate Bot
fe0b7bc95b fix(deps): update dependency @nestjs/swagger to v4.7.10 2021-01-12 10:27:10 +00:00
Renovate Bot
b876a5542c chore(deps): update dependency webpack to v5.13.0 2021-01-12 10:26:33 +00:00
Neranjen
b14c7de30b fix(common): update class-validator interfaces 2021-01-12 15:41:06 +05:30
Kamil Mysliwiec
439512a748 Merge pull request #6125 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.13.0
2021-01-12 09:07:23 +01:00
Renovate Bot
fa0024e581 chore(deps): update typescript-eslint monorepo to v4.13.0 2021-01-11 19:52:27 +00:00
Kamil Mysliwiec
854522eb88 Merge pull request #6099 from nestjs/renovate/fast-json-stringify-2.x
fix(deps): update dependency fast-json-stringify to v2.3.1
2021-01-11 08:47:17 +01:00
Kamil Mysliwiec
3f67e9a0f2 Merge pull request #6102 from nestjs/renovate/point-of-view-4.x
fix(deps): update dependency point-of-view to v4.8.0
2021-01-11 08:47:11 +01:00
Kamil Mysliwiec
b5a92dd1be Merge pull request #6103 from nestjs/renovate/socket.io-packages
fix(deps): update dependency socket.io to v2.4.1
2021-01-11 08:47:04 +01:00
Kamil Mysliwiec
9c15dc692d Merge pull request #6111 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.12.3
2021-01-11 08:46:48 +01:00
Kamil Mysliwiec
7efeba63c6 Merge pull request #6113 from nestjs/renovate/gulp-4.x
chore(deps): update dependency @types/gulp to v4.0.8
2021-01-11 08:46:25 +01:00
Kamil Mysliwiec
1db29b3632 Merge pull request #6114 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.11
2021-01-11 08:46:08 +01:00
Renovate Bot
32d06a2bea chore(deps): update dependency webpack to v5.12.3 2021-01-10 19:47:02 +00:00
Renovate Bot
a04d19b339 fix(deps): update dependency point-of-view to v4.8.0 2021-01-09 07:42:39 +00:00
Renovate Bot
27e1748ae9 fix(deps): update dependency fast-json-stringify to v2.3.1 2021-01-09 07:39:28 +00:00
Renovate Bot
025fb6bae9 fix(deps): update dependency mongoose to v5.11.11 2021-01-08 18:27:21 +00:00
Renovate Bot
d7fafd59ab chore(deps): update dependency @types/gulp to v4.0.8 2021-01-08 17:22:48 +00:00
Renovate Bot
54514b636b fix(deps): update dependency socket.io to v2.4.1 2021-01-07 12:13:06 +00:00
Kamil Mysliwiec
b0de6b20c7 Merge pull request #6070 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.10
2021-01-07 13:05:38 +01:00
Kamil Mysliwiec
d13fad341a Merge pull request #6101 from nestjs/renovate/nestjs-mongoose-7.x
fix(deps): update dependency @nestjs/mongoose to v7.2.1
2021-01-07 13:05:03 +01:00
Kamil Mysliwiec
ad955270cf Merge pull request #6091 from nestjs/renovate/nodemon-2.x
chore(deps): update dependency nodemon to v2.0.7
2021-01-07 11:53:59 +01:00
Kamil Mysliwiec
7f300dc640 Merge pull request #6098 from nestjs/renovate/jest-26.x
chore(deps): update dependency @types/jest to v26.0.20
2021-01-07 11:53:51 +01:00
Kamil Mysliwiec
06b220fd92 Merge pull request #6039 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.12.0
2021-01-07 11:50:04 +01:00
Renovate Bot
d823d9bf75 fix(deps): update dependency @nestjs/mongoose to v7.2.1 2021-01-07 10:13:53 +00:00
Renovate Bot
a58db3a89d chore(deps): update dependency nodemon to v2.0.7 2021-01-07 10:10:03 +00:00
Kamil Mysliwiec
3b8e4172e7 Merge pull request #6095 from nestjs/dependabot/npm_and_yarn/sinon-9.2.3
chore(deps-dev): bump sinon from 9.2.2 to 9.2.3
2021-01-07 11:08:08 +01:00
Kamil Mysliwiec
6cd9b7e6d4 Merge pull request #6097 from nestjs/dependabot/npm_and_yarn/nodemon-2.0.7
chore(deps-dev): bump nodemon from 2.0.6 to 2.0.7
2021-01-07 11:07:56 +01:00
Renovate Bot
989582529b fix(deps): update dependency mongoose to v5.11.10 2021-01-07 09:34:40 +00:00
Renovate Bot
5210db3050 chore(deps): update dependency @types/jest to v26.0.20 2021-01-07 09:30:09 +00:00
Kamil Mysliwiec
ae76f46e3c Merge pull request #6083 from nestjs/renovate/fastify-static-3.x
fix(deps): update dependency fastify-static to v3.3.1
2021-01-07 10:25:53 +01:00
Renovate Bot
9c102342d9 chore(deps): update typescript-eslint monorepo to v4.12.0 2021-01-07 09:17:47 +00:00
dependabot[bot]
7e79847c61 chore(deps-dev): bump nodemon from 2.0.6 to 2.0.7
Bumps [nodemon](https://github.com/remy/nodemon) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.6...v2.0.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-07 08:58:25 +00:00
dependabot[bot]
da4fc69e2b chore(deps-dev): bump sinon from 9.2.2 to 9.2.3
Bumps [sinon](https://github.com/sinonjs/sinon) from 9.2.2 to 9.2.3.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v9.2.2...v9.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-07 08:58:23 +00:00
Kamil Mysliwiec
25b6e501f8 Merge pull request #6078 from nestjs/dependabot/npm_and_yarn/engine.io-client-4.0.6
chore(deps-dev): bump engine.io-client from 4.0.5 to 4.0.6
2021-01-07 09:56:01 +01:00
Kamil Mysliwiec
1f4f8222b1 Merge pull request #6014 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.20
2021-01-07 09:30:25 +01:00
Renovate Bot
a85cd23088 fix(deps): update dependency fastify-static to v3.3.1 2021-01-07 08:19:04 +00:00
dependabot[bot]
b0cc4a2ec5 chore(deps-dev): bump engine.io-client from 4.0.5 to 4.0.6
Bumps [engine.io-client](https://github.com/socketio/engine.io-client) from 4.0.5 to 4.0.6.
- [Release notes](https://github.com/socketio/engine.io-client/releases)
- [Changelog](https://github.com/socketio/engine.io-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io-client/compare/4.0.5...4.0.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-07 07:52:34 +00:00
Kamil Mysliwiec
e235bcfcd5 Merge pull request #6079 from nestjs/dependabot/npm_and_yarn/typescript-eslint/parser-4.12.0
chore(deps-dev): bump @typescript-eslint/parser from 4.11.1 to 4.12.0
2021-01-07 08:50:34 +01:00
Kamil Mysliwiec
4841d48e93 Merge pull request #6084 from nestjs/renovate/ts-loader-8.x
chore(deps): update dependency ts-loader to v8.0.14
2021-01-07 08:50:25 +01:00
Kamil Mysliwiec
dac636f0c1 Merge pull request #6086 from nestjs/dependabot/npm_and_yarn/fastify-static-3.3.1
chore(deps-dev): bump fastify-static from 3.3.0 to 3.3.1
2021-01-07 08:50:15 +01:00
Kamil Mysliwiec
dfefa63697 Merge pull request #6089 from nestjs/dependabot/npm_and_yarn/tslib-2.1.0
chore(deps): bump tslib from 2.0.3 to 2.1.0
2021-01-07 08:50:03 +01:00
Kamil Mysliwiec
30e90b7a3a Merge pull request #6096 from nestjs/dependabot/npm_and_yarn/husky-4.3.7
chore(deps-dev): bump husky from 4.3.6 to 4.3.7
2021-01-07 08:49:50 +01:00
dependabot[bot]
045983d7aa chore(deps-dev): bump husky from 4.3.6 to 4.3.7
Bumps [husky](https://github.com/typicode/husky) from 4.3.6 to 4.3.7.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v4.3.6...v4.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-07 05:26:50 +00:00
dependabot[bot]
660be0ed86 chore(deps): bump tslib from 2.0.3 to 2.1.0
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.0.3 to 2.1.0.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/2.0.3...2.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-06 05:18:56 +00:00
dependabot[bot]
c523845855 chore(deps-dev): bump fastify-static from 3.3.0 to 3.3.1
Bumps [fastify-static](https://github.com/fastify/fastify-static) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/fastify/fastify-static/releases)
- [Commits](https://github.com/fastify/fastify-static/compare/v3.3.0...v3.3.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-06 05:08:48 +00:00
Renovate Bot
d560888761 chore(deps): update dependency ts-loader to v8.0.14 2021-01-05 19:47:51 +00:00
Jesse Carter
fdd678c013 fix(microservices): custom strategy typings 2021-01-05 08:05:02 -05:00
Renovate Bot
4950c53586 chore(deps): update dependency @types/node to v14.14.20 2021-01-05 09:25:28 +00:00
dependabot[bot]
57ebb8e04e chore(deps-dev): bump @typescript-eslint/parser from 4.11.1 to 4.12.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.11.1 to 4.12.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.12.0/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-05 07:56:56 +00:00
Kamil Mysliwiec
e77b185828 Merge pull request #6048 from nestjs/renovate/ws-7.x
fix(deps): update dependency ws to v7.4.2
2021-01-05 08:50:13 +01:00
Kamil Mysliwiec
bc74ef28a3 Merge pull request #6074 from nestjs/renovate/socket.io-packages
fix(deps): update socket.io packages to v2.4.0
2021-01-05 08:48:14 +01:00
Kamil Mysliwiec
9e6667f9e8 Merge pull request #6076 from nestjs/dependabot/npm_and_yarn/mongoose-5.11.10
chore(deps-dev): bump mongoose from 5.11.9 to 5.11.10
2021-01-05 08:47:58 +01:00
Kamil Mysliwiec
d74ae63e83 Merge pull request #6077 from nestjs/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.12.0
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.11.1 to 4.12.0
2021-01-05 08:47:51 +01:00
Kamil Mysliwiec
a4c475ddc2 Merge pull request #6080 from nestjs/dependabot/npm_and_yarn/types/node-14.14.20
chore(deps-dev): bump @types/node from 14.14.17 to 14.14.20
2021-01-05 08:45:36 +01:00
dependabot[bot]
aa4c8608ed chore(deps-dev): bump @types/node from 14.14.17 to 14.14.20
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.17 to 14.14.20.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-05 05:23:28 +00:00
dependabot[bot]
13b366878e chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.11.1 to 4.12.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.12.0/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-05 05:17:26 +00:00
dependabot[bot]
c6bf80f76c chore(deps-dev): bump mongoose from 5.11.9 to 5.11.10
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.11.9 to 5.11.10.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.11.9...5.11.10)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-05 05:15:33 +00:00
Renovate Bot
3080f75534 fix(deps): update socket.io packages to v2.4.0 2021-01-05 00:18:38 +00:00
Navid Nikpour
766218aad1 feat(testing): Changes Logger to LoggerService
to require the same interface that the underlying Logger class is expecting
2021-01-05 00:14:52 +01:00
Navid Nikpour
d6b2266615 feat(testing): adds builder method for optional custom logger
Adds a method that enables to set a new custom logger (extended from the Logger class) for testing. If this method is not used (therefore the logger gets never set) it falls back to the already existing TestingLogger of the testing module.
2021-01-04 22:53:13 +01:00
Renovate Bot
344f6a6efc fix(deps): update dependency ws to v7.4.2 2021-01-04 09:06:55 +00:00
Kamil Mysliwiec
9421dae875 Merge pull request #6040 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.9
2021-01-04 09:40:20 +01:00
Kamil Mysliwiec
27dafd8292 Merge pull request #6044 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.4
2021-01-04 09:40:09 +01:00
Kamil Mysliwiec
5150334252 Merge pull request #6068 from nestjs/dependabot/npm_and_yarn/core-js-3.8.2
chore(deps-dev): bump core-js from 3.8.1 to 3.8.2
2021-01-04 09:39:34 +01:00
dependabot[bot]
6f9ae1c871 chore(deps-dev): bump core-js from 3.8.1 to 3.8.2
Bumps [core-js](https://github.com/zloirock/core-js) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.8.1...v3.8.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-04 05:36:19 +00:00
Renovate Bot
65c6c443a6 fix(deps): update dependency @nestjs/graphql to v7.9.4 2021-01-03 10:23:38 +00:00
Kamil Mysliwiec
732d378c62 Merge pull request #6058 from nestjs/renovate/webpack-cli-4.x
chore(deps): update dependency webpack-cli to v4.3.1
2021-01-03 10:57:46 +01:00
Kamil Mysliwiec
55033eb6b4 Merge pull request #6052 from nestjs/dependabot/npm_and_yarn/nestjs/graphql-7.9.4
chore(deps-dev): bump @nestjs/graphql from 7.9.2 to 7.9.4
2021-01-03 10:57:40 +01:00
Kamil Mysliwiec
5f103779b4 Merge pull request #6055 from nestjs/dependabot/npm_and_yarn/types/node-14.14.17
chore(deps-dev): bump @types/node from 14.14.16 to 14.14.17
2021-01-03 10:57:28 +01:00
Kamil Mysliwiec
2753474871 Merge pull request #6056 from nestjs/renovate/ts-loader-8.x
chore(deps): update dependency ts-loader to v8.0.13
2021-01-03 10:56:41 +01:00
Kamil Mysliwiec
aeec26c25a Merge pull request #6063 from nestjs/renovate/eslint-7.x
chore(deps): update dependency eslint to v7.17.0
2021-01-03 10:56:19 +01:00
Renovate Bot
55d7542cb1 chore(deps): update dependency eslint to v7.17.0 2021-01-02 03:41:39 +00:00
Tony133
987faa5f2e chore(microservice): added key for extra values 2021-01-01 22:52:17 +01:00
Tony133
c5aa2c7b01 chore(microservice): updated nats options ref:6054 2021-01-01 19:15:44 +01:00
Renovate Bot
73059b574f chore(deps): update dependency webpack-cli to v4.3.1 2020-12-31 18:49:22 +00:00
Renovate Bot
98c9674b26 chore(deps): update dependency ts-loader to v8.0.13 2020-12-31 07:04:05 +00:00
dependabot[bot]
a1c76b4a7e chore(deps-dev): bump @types/node from 14.14.16 to 14.14.17
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.16 to 14.14.17.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-31 05:06:15 +00:00
Renovate Bot
eabc87063e fix(deps): update dependency mongoose to v5.11.9 2020-12-30 10:12:34 +00:00
Kamil Mysliwiec
562cd3d6ee Merge pull request #6043 from nestjs/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.11.1
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.11.0 to 4.11.1
2020-12-30 10:56:39 +01:00
Kamil Mysliwiec
4b35074d5c Merge pull request #6049 from nestjs/dependabot/npm_and_yarn/ws-7.4.2
chore(deps): bump ws from 7.4.1 to 7.4.2
2020-12-30 10:56:27 +01:00
dependabot[bot]
287b8a4371 chore(deps-dev): bump @nestjs/graphql from 7.9.2 to 7.9.4
Bumps [@nestjs/graphql](https://github.com/nestjs/graphql) from 7.9.2 to 7.9.4.
- [Release notes](https://github.com/nestjs/graphql/releases)
- [Changelog](https://github.com/nestjs/graphql/blob/master/.release-it.json)
- [Commits](https://github.com/nestjs/graphql/compare/7.9.2...7.9.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-30 09:42:30 +00:00
dependabot[bot]
b627789e7e chore(deps): bump ws from 7.4.1 to 7.4.2
Bumps [ws](https://github.com/websockets/ws) from 7.4.1 to 7.4.2.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.1...7.4.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-30 09:42:20 +00:00
Kamil Mysliwiec
c313e14add Merge pull request #6051 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.5
2020-12-30 10:39:55 +01:00
Renovate Bot
a0a2aeba77 fix(deps): update nest monorepo to v7.6.5 2020-12-30 09:27:43 +00:00
Kamil Myśliwiec
70724f4aed chore(@nestjs) publish v7.6.5 release 2020-12-30 09:50:54 +01:00
Kamil Myśliwiec
fcccd4ccad Merge branch 'master' of https://github.com/nestjs/nest 2020-12-30 09:48:03 +01:00
Kamil Myśliwiec
a45039ae45 fix(core): use dynamic metadata to generate a hash (context) 2020-12-30 09:47:56 +01:00
dependabot[bot]
a2c6cb3ef9 chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.11.0 to 4.11.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.11.1/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-29 09:26:15 +00:00
Kamil Mysliwiec
7b411cb57d Merge pull request #6036 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.9
2020-12-29 10:23:02 +01:00
Kamil Mysliwiec
b75802cadc Merge pull request #6038 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.11.1
2020-12-29 10:22:51 +01:00
Kamil Mysliwiec
65663d3328 Merge pull request #6041 from nestjs/dependabot/npm_and_yarn/mongoose-5.11.9
chore(deps-dev): bump mongoose from 5.11.8 to 5.11.9
2020-12-29 10:22:18 +01:00
Kamil Mysliwiec
93d7962d10 Merge pull request #6042 from nestjs/dependabot/npm_and_yarn/typescript-eslint/parser-4.11.1
chore(deps-dev): bump @typescript-eslint/parser from 4.11.0 to 4.11.1
2020-12-29 10:22:11 +01:00
dependabot[bot]
e27b236dbe chore(deps-dev): bump @typescript-eslint/parser from 4.11.0 to 4.11.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.11.0 to 4.11.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.11.1/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-29 05:27:37 +00:00
dependabot[bot]
62afe6729c chore(deps-dev): bump mongoose from 5.11.8 to 5.11.9
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.11.8 to 5.11.9.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.11.8...5.11.9)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-29 05:25:53 +00:00
Renovate Bot
6551398a9b chore(deps): update dependency webpack to v5.11.1 2020-12-28 19:28:41 +00:00
Renovate Bot
40dbd07fc8 fix(deps): update dependency @nestjs/swagger to v4.7.9 2020-12-28 12:14:11 +00:00
Kamil Mysliwiec
be1a75c57f Merge pull request #6025 from nestjs/renovate/amqplib-0.x
chore(deps): update dependency @types/amqplib to v0.5.17
2020-12-28 13:12:11 +01:00
Renovate Bot
d1e6666eeb chore(deps): update dependency @types/amqplib to v0.5.17 2020-12-28 11:33:35 +00:00
Kamil Mysliwiec
4daefbf020 Merge pull request #6004 from nestjs/renovate/docker-confluentinc-cp-kafka-5.x
chore(deps): update confluentinc/cp-kafka docker tag to v5.5.3
2020-12-28 12:30:44 +01:00
Kamil Mysliwiec
a919dd237b Merge pull request #6034 from nestjs/renovate/nestjs-graphql-7.x
fix(deps): update dependency @nestjs/graphql to v7.9.2
2020-12-28 12:30:33 +01:00
Kamil Mysliwiec
c59e955901 Merge pull request #6033 from nestjs/renovate/nestjs-schematics-7.x
chore(deps): update dependency @nestjs/schematics to v7.2.6
2020-12-28 12:30:17 +01:00
Renovate Bot
9a2a8b80bf fix(deps): update dependency @nestjs/graphql to v7.9.2 2020-12-28 11:09:15 +00:00
Renovate Bot
a880fc886e chore(deps): update dependency @nestjs/schematics to v7.2.6 2020-12-28 11:04:54 +00:00
Renovate Bot
8cdfa23815 chore(deps): update confluentinc/cp-kafka docker tag to v5.5.3 2020-12-28 08:40:54 +00:00
Kamil Mysliwiec
3cfa0c74d2 Merge pull request #6021 from nestjs/renovate/webpack-cli-4.x
chore(deps): update dependency webpack-cli to v4.3.0
2020-12-28 09:36:51 +01:00
Kamil Mysliwiec
b4938d8721 Merge pull request #6029 from nestjs/dependabot/npm_and_yarn/types/amqplib-0.5.17
chore(deps-dev): bump @types/amqplib from 0.5.16 to 0.5.17
2020-12-28 09:36:38 +01:00
Kamil Mysliwiec
7ef921aca1 Merge pull request #6011 from nestjs/renovate/babel-monorepo
chore(deps): update dependency @babel/plugin-proposal-decorators to v7.12.12
2020-12-28 09:34:43 +01:00
Kamil Mysliwiec
acd2d26d53 Merge pull request #6015 from nestjs/dependabot/npm_and_yarn/types/node-14.14.16
chore(deps-dev): bump @types/node from 14.14.14 to 14.14.16
2020-12-28 09:34:38 +01:00
Kamil Mysliwiec
37c5d16db3 Merge pull request #6016 from nestjs/dependabot/npm_and_yarn/types/sinon-9.0.10
chore(deps-dev): bump @types/sinon from 9.0.9 to 9.0.10
2020-12-28 09:34:32 +01:00
Kamil Mysliwiec
7c93e55ccb Merge pull request #6030 from nestjs/dependabot/npm_and_yarn/object-hash-2.1.1
chore(deps): bump object-hash from 2.0.3 to 2.1.1
2020-12-28 09:34:01 +01:00
dependabot[bot]
54186a429f chore(deps): bump object-hash from 2.0.3 to 2.1.1
Bumps [object-hash](https://github.com/puleos/object-hash) from 2.0.3 to 2.1.1.
- [Release notes](https://github.com/puleos/object-hash/releases)
- [Commits](https://github.com/puleos/object-hash/compare/v2.0.3...v2.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:41 +00:00
dependabot[bot]
0321d77dcd chore(deps-dev): bump @types/amqplib from 0.5.16 to 0.5.17
Bumps [@types/amqplib](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/amqplib) from 0.5.16 to 0.5.17.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/amqplib)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:36:18 +00:00
Renovate Bot
66a1430a85 chore(deps): update dependency webpack-cli to v4.3.0 2020-12-25 18:33:03 +00:00
dependabot[bot]
861a53c3d3 chore(deps-dev): bump @types/sinon from 9.0.9 to 9.0.10
Bumps [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) from 9.0.9 to 9.0.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-24 05:24:00 +00:00
dependabot[bot]
15213d93c3 chore(deps-dev): bump @types/node from 14.14.14 to 14.14.16
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.16.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-24 05:21:39 +00:00
Renovate Bot
7aedd0cc88 chore(deps): update dependency @babel/plugin-proposal-decorators to v7.12.12 2020-12-23 14:09:09 +00:00
Kamil Mysliwiec
bfc7bea887 Merge pull request #6002 from nestjs/dependabot/npm_and_yarn/sample/13-mongo-typeorm/node-notifier-8.0.1
chore(deps): bump node-notifier from 8.0.0 to 8.0.1 in /sample/13-mongo-typeorm
2020-12-23 09:02:10 +01:00
Kamil Mysliwiec
428605e63a Merge pull request #6005 from nestjs/renovate/docker-confluentinc-cp-zookeeper-5.x
chore(deps): update confluentinc/cp-zookeeper docker tag to v5.5.3
2020-12-23 09:01:42 +01:00
Kamil Mysliwiec
61022bea9c Merge pull request #6006 from nestjs/renovate/swagger-ui-express-4.x
fix(deps): update dependency swagger-ui-express to v4.1.6
2020-12-23 09:01:32 +01:00
Kamil Mysliwiec
e0df855423 Merge pull request #6007 from nestjs/renovate/apollo-graphql-packages
fix(deps): update apollo graphql packages to v2.19.1
2020-12-23 09:00:57 +01:00
Renovate Bot
9a806d6851 fix(deps): update apollo graphql packages to v2.19.1 2020-12-22 23:13:18 +00:00
Renovate Bot
28cb30743b fix(deps): update dependency swagger-ui-express to v4.1.6 2020-12-22 20:25:54 +00:00
Renovate Bot
85dcd8a2fe chore(deps): update confluentinc/cp-zookeeper docker tag to v5.5.3 2020-12-22 19:49:35 +00:00
dependabot[bot]
97b9836a58 chore(deps): bump node-notifier in /sample/13-mongo-typeorm
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-22 13:54:50 +00:00
Kamil Mysliwiec
bfdc8f4025 Merge pull request #6001 from nestjs/dependabot/npm_and_yarn/sample/01-cats-app/node-notifier-8.0.1
chore(deps): bump node-notifier from 8.0.0 to 8.0.1 in /sample/01-cats-app
2020-12-22 11:08:26 +01:00
dependabot[bot]
f1bc0b709d chore(deps): bump node-notifier in /sample/01-cats-app
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-22 08:02:18 +00:00
Kamil Mysliwiec
9304c56847 Merge pull request #5996 from nestjs/renovate/axios-0.x
fix(deps): update dependency axios to v0.21.1
2020-12-22 08:37:21 +01:00
Kamil Mysliwiec
ca487ce995 Merge pull request #5992 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.11.0
2020-12-22 08:31:11 +01:00
Renovate Bot
4603979d67 fix(deps): update dependency axios to v0.21.1 2020-12-22 04:30:40 +00:00
Renovate Bot
658e26b274 chore(deps): update typescript-eslint monorepo to v4.11.0 2020-12-21 19:19:24 +00:00
Krystian Sztadhaus
86051702b8 chore: Run linter without --fix on CI 2020-12-21 22:26:44 +04:00
Kamil Mysliwiec
c061debf1a Merge pull request #5991 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.4
2020-12-21 15:10:23 +01:00
Renovate Bot
9be7fc5277 fix(deps): update nest monorepo to v7.6.4 2020-12-21 12:41:20 +00:00
Kamil Myśliwiec
1957d75db7 chore(@nestjs) publish v7.6.4 release 2020-12-21 13:15:57 +01:00
Kamil Mysliwiec
82a57093ba Merge pull request #5982 from Tony133/chore/update-serializer-interceptor
chore(serializer): changed visibility indicator
2020-12-21 12:52:42 +01:00
Kamil Mysliwiec
ad657f9aa5 Merge pull request #5989 from maximeag/patch-1
fix(microservices): fix kafka config field typo
2020-12-21 12:49:39 +01:00
Kamil Myśliwiec
0b7ca5f6f3 Merge branch 'Hwan-seok-apply-stderr-log' 2020-12-21 12:49:21 +01:00
Kamil Myśliwiec
fdcb89d0d0 refactor(common): minor tweaks 2020-12-21 12:49:09 +01:00
Kamil Myśliwiec
01d0271b9c Merge branch 'apply-stderr-log' of https://github.com/Hwan-seok/nest into Hwan-seok-apply-stderr-log 2020-12-21 12:48:07 +01:00
Kamil Mysliwiec
5f24eebf25 Merge pull request #5984 from nestjs/renovate/eslint-config-prettier-7.x
chore(deps): update dependency eslint-config-prettier to v7.1.0
2020-12-21 11:21:17 +01:00
Renovate Bot
2e33120949 chore(deps): update dependency eslint-config-prettier to v7.1.0 2020-12-21 10:01:04 +00:00
Maxime
0ff0c86631 fix(microservices): fix kafka config field typo 2020-12-21 10:44:16 +01:00
Kamil Mysliwiec
a55b27745f Merge pull request #5983 from nestjs/renovate/eslint-7.x
chore(deps): update dependency eslint to v7.16.0
2020-12-21 09:15:40 +01:00
Renovate Bot
fcb9cec9c8 chore(deps): update dependency eslint to v7.16.0 2020-12-21 08:08:44 +00:00
Kamil Mysliwiec
3b6a8ba1de Merge pull request #5988 from nestjs/dependabot/npm_and_yarn/eslint-config-prettier-7.1.0
chore(deps-dev): bump eslint-config-prettier from 7.0.0 to 7.1.0
2020-12-21 08:21:10 +01:00
dependabot[bot]
d1d08ac2ef chore(deps-dev): bump eslint-config-prettier from 7.0.0 to 7.1.0
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v7.0.0...v7.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:40:10 +00:00
Hwan-seok
c7a4128631 feat(common): change error log to use stderr 2020-12-21 10:08:04 +09:00
Tony133
e8d6e312bb chore(serializer): changed visibility indicator 2020-12-18 17:56:44 +01:00
Kamil Mysliwiec
2525e9406d Merge pull request #5966 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.8
2020-12-18 08:59:43 +01:00
Kamil Mysliwiec
b7e916c8de Merge pull request #5970 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.11.0
2020-12-18 08:59:36 +01:00
Kamil Mysliwiec
d456c73f85 Merge pull request #5973 from nestjs/renovate/fast-json-stringify-2.x
fix(deps): update dependency fast-json-stringify to v2.3.0
2020-12-18 08:58:50 +01:00
Andrew Dassonville
dd51cf8f51 feat(): accept array of host filters
Allows an array of host filters to be passed to the @Controller decorator.
2020-12-17 16:36:45 -08:00
Renovate Bot
2ec37298e0 fix(deps): update dependency fast-json-stringify to v2.3.0 2020-12-17 18:09:15 +00:00
Renovate Bot
e8e2cc2f38 chore(deps): update dependency webpack to v5.11.0 2020-12-17 16:18:33 +00:00
Renovate Bot
b86d25ddf8 fix(deps): update dependency @nestjs/swagger to v4.7.8 2020-12-17 13:57:19 +00:00
Kamil Mysliwiec
3a700e2d19 Merge pull request #5965 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.3
2020-12-17 13:14:18 +01:00
Renovate Bot
95ef3a778c fix(deps): update nest monorepo to v7.6.3 2020-12-17 11:55:37 +00:00
Kamil Myśliwiec
bcd4ea93b1 chore(@nestjs) publish v7.6.3 release 2020-12-17 12:29:07 +01:00
Kamil Myśliwiec
0cc464519f Merge branch 'master' of https://github.com/nestjs/nest 2020-12-17 12:23:26 +01:00
Kamil Myśliwiec
bacef33be1 fix(core): properly serialise symbols in dynamic modules #5964 2020-12-17 12:23:17 +01:00
Kamil Mysliwiec
c624c170dd Merge pull request #5915 from nestjs/fix/5701-await-kafka-response
fix(microservices): await respond callback, fix kafka (missing second-to-last item)
2020-12-17 12:19:56 +01:00
Kamil Mysliwiec
d9c4162bb2 Merge pull request #5929 from nestjs/renovate/typescript-4.x
chore(deps): update dependency typescript to v4.1.3
2020-12-17 12:19:45 +01:00
Kamil Mysliwiec
fc557353be Merge pull request #5963 from nestjs/renovate/light-my-request-4.x
fix(deps): update dependency light-my-request to v4.4.1
2020-12-17 12:02:06 +01:00
Renovate Bot
6c800fd2e3 fix(deps): update dependency light-my-request to v4.4.1 2020-12-17 10:28:33 +00:00
Kamil Mysliwiec
cee29d9406 Merge pull request #5962 from nestjs/renovate/nest-monorepo
fix(deps): update nest monorepo to v7.6.2
2020-12-17 09:37:17 +01:00
Renovate Bot
7d7cf01813 fix(deps): update nest monorepo to v7.6.2 2020-12-17 08:11:17 +00:00
Kamil Myśliwiec
a05ff8b6b0 chore(@nestjs) publish v7.6.2 release 2020-12-17 08:45:38 +01:00
Kamil Myśliwiec
b63cd49f83 Merge branch 'master' of https://github.com/nestjs/nest 2020-12-17 08:44:33 +01:00
Kamil Myśliwiec
be6c85c88d fix(common): fix undefined get timestamp method (logger) 2020-12-17 08:44:11 +01:00
Kamil Mysliwiec
93acb0af17 Merge pull request #5955 from nestjs/renovate/fastify-3.x
fix(deps): update dependency fastify to v3.9.2
2020-12-16 14:35:46 +01:00
Renovate Bot
a80547e4a6 chore(deps): update dependency typescript to v4.1.3 2020-12-16 13:33:33 +00:00
Renovate Bot
16246feddd fix(deps): update dependency fastify to v3.9.2 2020-12-16 13:09:59 +00:00
Kamil Mysliwiec
1a43fd05e8 Merge pull request #5932 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.14
2020-12-16 14:04:19 +01:00
Kamil Mysliwiec
24ce1dd6de Merge pull request #5954 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.7
2020-12-16 11:47:48 +01:00
Renovate Bot
51a2e48a4a fix(deps): update dependency @nestjs/swagger to v4.7.7 2020-12-16 10:16:01 +00:00
Renovate Bot
a3f32a342d chore(deps): update dependency @types/node to v14.14.14 2020-12-16 07:54:01 +00:00
Kamil Mysliwiec
9f96855a46 Merge pull request #5949 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.10.3
2020-12-16 08:34:46 +01:00
Kamil Mysliwiec
e2e2a8f746 Merge pull request #5934 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.8
2020-12-16 08:34:10 +01:00
Kamil Mysliwiec
094fc36115 Merge pull request #5938 from nestjs/dependabot/npm_and_yarn/typescript-4.1.3
chore(deps-dev): bump typescript from 4.1.2 to 4.1.3
2020-12-16 08:34:02 +01:00
Kamil Mysliwiec
854bf58910 Merge pull request #5951 from nestjs/renovate/babel-monorepo
chore(deps): update dependency @babel/preset-env to v7.12.11
2020-12-16 08:33:52 +01:00
Kamil Mysliwiec
5cba807a98 Merge pull request #5953 from nestjs/dependabot/npm_and_yarn/types/node-14.14.14
chore(deps-dev): bump @types/node from 14.14.13 to 14.14.14
2020-12-16 08:33:45 +01:00
dependabot[bot]
8df77f8f45 chore(deps-dev): bump @types/node from 14.14.13 to 14.14.14
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.13 to 14.14.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-16 05:27:26 +00:00
Renovate Bot
a796bfabea chore(deps): update dependency @babel/preset-env to v7.12.11 2020-12-16 00:09:19 +00:00
Renovate Bot
f6f6f917ad chore(deps): update dependency webpack to v5.10.3 2020-12-15 20:16:52 +00:00
Renovate Bot
f5770bf13b fix(deps): update dependency mongoose to v5.11.8 2020-12-15 10:02:46 +00:00
dependabot[bot]
1a4530e669 chore(deps-dev): bump typescript from 4.1.2 to 4.1.3
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 08:06:10 +00:00
Kamil Mysliwiec
2b1529923e Merge pull request #5930 from nestjs/renovate/webpack-5.x
chore(deps): update dependency webpack to v5.10.1
2020-12-15 09:04:08 +01:00
Kamil Mysliwiec
69e229774c Merge pull request #5947 from nestjs/dependabot/npm_and_yarn/clang-format-1.5.0
chore(deps-dev): bump clang-format from 1.4.0 to 1.5.0
2020-12-15 09:03:54 +01:00
Kamil Mysliwiec
82eb97401b Merge pull request #5948 from nestjs/dependabot/npm_and_yarn/mongoose-5.11.8
chore(deps-dev): bump mongoose from 5.11.7 to 5.11.8
2020-12-15 09:03:47 +01:00
Kamil Mysliwiec
5134ccd933 Merge pull request #5944 from nestjs/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v4.10.0
2020-12-15 09:03:26 +01:00
dependabot[bot]
e23970d748 chore(deps-dev): bump mongoose from 5.11.7 to 5.11.8
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.11.7 to 5.11.8.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.11.7...5.11.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 05:38:57 +00:00
dependabot[bot]
3102db3aa0 chore(deps-dev): bump clang-format from 1.4.0 to 1.5.0
Bumps [clang-format](https://github.com/angular/clang-format) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/angular/clang-format/releases)
- [Commits](https://github.com/angular/clang-format/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 05:34:54 +00:00
Renovate Bot
452ffb4125 chore(deps): update typescript-eslint monorepo to v4.10.0 2020-12-14 18:24:07 +00:00
Renovate Bot
5a33605808 chore(deps): update dependency webpack to v5.10.1 2020-12-14 12:06:18 +00:00
Kamil Mysliwiec
51a5de1287 Merge pull request #5939 from nestjs/dependabot/npm_and_yarn/types/node-14.14.13
chore(deps-dev): bump @types/node from 14.14.12 to 14.14.13
2020-12-14 12:51:21 +01:00
Kamil Mysliwiec
a64116b2bf Merge pull request #5936 from nestjs/dependabot/npm_and_yarn/husky-4.3.6
chore(deps-dev): bump husky from 4.3.5 to 4.3.6
2020-12-14 12:28:55 +01:00
Kamil Mysliwiec
1426d4c860 Merge pull request #5940 from nestjs/dependabot/npm_and_yarn/sinon-9.2.2
chore(deps-dev): bump sinon from 9.2.1 to 9.2.2
2020-12-14 12:28:49 +01:00
dependabot[bot]
24113d9de9 chore(deps-dev): bump @types/node from 14.14.12 to 14.14.13
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.12 to 14.14.13.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 10:52:35 +00:00
Kamil Mysliwiec
33e2c65892 Merge pull request #5941 from nestjs/renovate/nestjs-swagger-4.x
fix(deps): update dependency @nestjs/swagger to v4.7.6
2020-12-14 11:50:19 +01:00
Kamil Mysliwiec
c21a1526ad Merge pull request #5937 from nestjs/dependabot/npm_and_yarn/types/mongoose-5.10.3
chore(deps-dev): bump @types/mongoose from 5.10.2 to 5.10.3
2020-12-14 11:50:03 +01:00
dependabot[bot]
f1d1ab8a03 chore(deps-dev): bump husky from 4.3.5 to 4.3.6
Bumps [husky](https://github.com/typicode/husky) from 4.3.5 to 4.3.6.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v4.3.5...v4.3.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 10:26:14 +00:00
dependabot[bot]
0d902753c9 chore(deps-dev): bump @types/mongoose from 5.10.2 to 5.10.3
Bumps [@types/mongoose](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mongoose) from 5.10.2 to 5.10.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mongoose)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 10:26:12 +00:00
dependabot[bot]
ef172c3e21 chore(deps-dev): bump sinon from 9.2.1 to 9.2.2
Bumps [sinon](https://github.com/sinonjs/sinon) from 9.2.1 to 9.2.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/commits/v9.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 10:26:05 +00:00
Renovate Bot
ae6f24b9fe fix(deps): update dependency @nestjs/swagger to v4.7.6 2020-12-14 10:25:41 +00:00
Kamil Myśliwiec
8db37bdbbe Merge branch 'master' of https://github.com/nestjs/nest 2020-12-11 13:33:15 +01:00
Kamil Myśliwiec
0b21ccb216 test(core): fix injector unit tests 2020-12-11 13:33:02 +01:00
Kamil Mysliwiec
a02be476fc Merge pull request #5926 from nestjs/renovate/nestjs-bull-0.x
fix(deps): update dependency @nestjs/bull to v0.3.1
2020-12-11 13:22:20 +01:00
Renovate Bot
b2e964a611 fix(deps): update dependency @nestjs/bull to v0.3.1 2020-12-11 12:13:36 +00:00
Kamil Mysliwiec
594ea3a734 Merge pull request #5914 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.12
2020-12-11 13:11:35 +01:00
Kamil Myśliwiec
bcc3fd3881 fix(core): fix injection of transient providers to middleware #5427 2020-12-11 12:24:51 +01:00
Renovate Bot
0dd86eb730 chore(deps): update dependency @types/node to v14.14.12 2020-12-11 11:10:21 +00:00
Kamil Myśliwiec
3dbf5f81f2 refactor(core): a few tweaks to the injector class 2020-12-11 11:39:42 +01:00
Kamil Mysliwiec
495de37512 Merge pull request #5918 from nestjs/renovate/jest-26.x
chore(deps): update dependency @types/jest to v26.0.19
2020-12-11 11:32:10 +01:00
Kamil Myśliwiec
9628c2dd76 Merge branch 'master' into fix/5701-await-kafka-response 2020-12-11 11:19:37 +01:00
Kamil Myśliwiec
85e50eb8e7 test(microservices): mock send method to return a promise (kafka client) 2020-12-11 11:19:24 +01:00
Kamil Myśliwiec
44f039820d Merge branch 'master' into fix/5701-await-kafka-response 2020-12-11 11:03:44 +01:00
Kamil Myśliwiec
b0e37bb746 Merge branch 'master' of https://github.com/nestjs/nest 2020-12-11 11:03:31 +01:00
Kamil Myśliwiec
9d0c96e953 fix(microservices): catch async errors when trying to send a message (kafka) 2020-12-11 11:03:19 +01:00
Renovate Bot
a3366e11a5 chore(deps): update dependency @types/jest to v26.0.19 2020-12-11 09:28:20 +00:00
Kamil Mysliwiec
e06be8fb30 Merge pull request #5891 from nestjs/renovate/kafkajs-1.x
chore(deps): update dependency kafkajs to v1.15.0
2020-12-11 09:40:56 +01:00
Kamil Mysliwiec
5da76830fe Merge pull request #5898 from nestjs/dependabot/npm_and_yarn/typescript-eslint/parser-4.9.1
chore(deps-dev): bump @typescript-eslint/parser from 4.9.0 to 4.9.1
2020-12-11 09:40:46 +01:00
Kamil Mysliwiec
8409a18420 Merge pull request #5913 from nestjs/renovate/nest-monorepo
chore(deps): update nest monorepo
2020-12-11 09:40:25 +01:00
Kamil Mysliwiec
413ca1990e Merge pull request #5923 from nestjs/dependabot/npm_and_yarn/types/cors-2.8.9
chore(deps-dev): bump @types/cors from 2.8.8 to 2.8.9
2020-12-11 09:28:21 +01:00
Kamil Mysliwiec
b10c3cb30e Merge pull request #5924 from nestjs/renovate/ts-loader-8.x
chore(deps): update dependency ts-loader to v8.0.12
2020-12-11 09:28:08 +01:00
Renovate Bot
61ee778554 chore(deps): update nest monorepo 2020-12-11 08:21:56 +00:00
Kamil Mysliwiec
ceb7ff8628 Merge pull request #5921 from nestjs/dependabot/npm_and_yarn/types/node-14.14.12
chore(deps-dev): bump @types/node from 14.14.11 to 14.14.12
2020-12-11 09:07:48 +01:00
dependabot[bot]
192ae54de0 chore(deps-dev): bump @typescript-eslint/parser from 4.9.0 to 4.9.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.9.0 to 4.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.9.1/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 07:59:28 +00:00
Kamil Mysliwiec
66a1231a0c Merge pull request #5919 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.7
2020-12-11 08:56:43 +01:00
Renovate Bot
09f5af366a chore(deps): update dependency ts-loader to v8.0.12 2020-12-11 06:33:46 +00:00
dependabot[bot]
d8d71b0c15 chore(deps-dev): bump @types/cors from 2.8.8 to 2.8.9
Bumps [@types/cors](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/cors) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/cors)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 05:17:01 +00:00
dependabot[bot]
a8186d8160 chore(deps-dev): bump @types/node from 14.14.11 to 14.14.12
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.11 to 14.14.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 05:12:30 +00:00
Renovate Bot
8d3f139286 fix(deps): update dependency mongoose to v5.11.7 2020-12-11 00:42:31 +00:00
Kamil Myśliwiec
bbf091c77c chore(@nestjs) publish v7.6.1 release 2020-12-10 12:34:14 +01:00
Kamil Myśliwiec
192d22f5e0 fix(common): add validate path alias for add leading slash fn (regression) 2020-12-10 12:33:04 +01:00
Renovate Bot
2ec1281b17 chore(deps): update dependency kafkajs to v1.15.0 2020-12-10 10:39:32 +00:00
Kamil Myśliwiec
b8a9772d51 test(microservices): fix server kafka unit tests 2020-12-10 11:30:58 +01:00
Kamil Myśliwiec
021c32380b fix(microservices): await respond callback, return promise to await (kafka) #5701 2020-12-10 10:53:49 +01:00
Kamil Mysliwiec
72cd8ff732 Merge pull request #5906 from nestjs/renovate/mongoose-5.x
fix(deps): update dependency mongoose to v5.11.6
2020-12-10 10:29:05 +01:00
Renovate Bot
fdb93219ad fix(deps): update dependency mongoose to v5.11.6 2020-12-10 09:18:40 +00:00
Kamil Myśliwiec
a9451b64fc chore(@nestjs) publish v7.6.0 release 2020-12-10 10:10:11 +01:00
Kamil Mysliwiec
d36c938548 Merge pull request #5908 from nestjs/renovate/babel-monorepo
chore(deps): update babel monorepo to v7.12.10
2020-12-10 09:47:57 +01:00
Kamil Mysliwiec
63048baf99 Merge pull request #5910 from nestjs/dependabot/npm_and_yarn/mongoose-5.11.6
chore(deps-dev): bump mongoose from 5.11.5 to 5.11.6
2020-12-10 09:47:49 +01:00
Kamil Mysliwiec
a52001dfb9 Merge pull request #5911 from nestjs/dependabot/npm_and_yarn/fastify-cors-5.1.0
chore(deps): bump fastify-cors from 5.0.0 to 5.1.0
2020-12-10 09:47:37 +01:00
dependabot[bot]
bb38257d13 chore(deps): bump fastify-cors from 5.0.0 to 5.1.0
Bumps [fastify-cors](https://github.com/fastify/fastify-cors) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/fastify/fastify-cors/releases)
- [Commits](https://github.com/fastify/fastify-cors/compare/v5.0.0...v5.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-10 05:30:47 +00:00
dependabot[bot]
703afcb1ba chore(deps-dev): bump mongoose from 5.11.5 to 5.11.6
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.11.5 to 5.11.6.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.11.5...5.11.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-10 05:27:59 +00:00
Renovate Bot
80f5a9ce48 chore(deps): update babel monorepo to v7.12.10 2020-12-09 22:51:30 +00:00
Kamil Myśliwiec
5a23bc1749 Merge branch 'andreialecu-andreialecu-patch-1' 2020-12-09 14:37:40 +01:00
Kamil Myśliwiec
bb6b643645 fix(): temporarily revert #5790 (breaking changes) 2020-12-09 14:37:26 +01:00
Kamil Myśliwiec
710b385a32 chore(): merge master 2020-12-09 14:11:38 +01:00
Kamil Mysliwiec
e78f364ef4 Merge pull request #5890 from nestjs/renovate/engine.io-client-4.x
chore(deps): update dependency engine.io-client to v4.0.5
2020-12-09 14:01:19 +01:00
Kamil Mysliwiec
23ce8d03e4 Merge pull request #5892 from nestjs/renovate/node-14.x
chore(deps): update dependency @types/node to v14.14.11
2020-12-09 14:01:06 +01:00
Kamil Myśliwiec
4c4d8039b8 Merge branch 'master' of https://github.com/nestjs/nest 2020-12-09 13:56:00 +01:00
Kamil Myśliwiec
016c6b554b fix(microservices): remove duplicated imports 2020-12-09 13:55:48 +01:00
Renovate Bot
3f5aad635b chore(deps): update dependency engine.io-client to v4.0.5 2020-12-09 08:21:00 +00:00
Renovate Bot
1c500b4bfc chore(deps): update dependency @types/node to v14.14.11 2020-12-09 08:08:06 +00:00
Kamil Mysliwiec
cad68b6d46 Merge pull request #5894 from nestjs/renovate/jest-26.x
chore(deps): update dependency @types/jest to v26.0.18
2020-12-09 08:43:37 +01:00
Kamil Mysliwiec
a22abe53b5 Merge pull request #5886 from nestjs/renovate/pin-dependencies
fix(deps): pin dependencies
2020-12-09 08:34:20 +01:00
Kamil Mysliwiec
65afede473 Merge pull request #5896 from nestjs/dependabot/npm_and_yarn/types/mocha-8.2.0
chore(deps-dev): bump @types/mocha from 8.0.4 to 8.2.0
2020-12-09 08:33:33 +01:00
Kamil Mysliwiec
171b53c3fb Merge pull request #5897 from nestjs/dependabot/npm_and_yarn/types/node-14.14.11
chore(deps-dev): bump @types/node from 14.14.10 to 14.14.11
2020-12-09 08:33:26 +01:00
Kamil Mysliwiec
8875d431b4 Merge pull request #5900 from nestjs/dependabot/npm_and_yarn/nestjs/mongoose-7.2.0
chore(deps-dev): bump @nestjs/mongoose from 7.1.2 to 7.2.0
2020-12-09 08:33:02 +01:00
Kamil Mysliwiec
0d078a0188 Merge pull request #5901 from nestjs/dependabot/npm_and_yarn/uuid-8.3.2
chore(deps): bump uuid from 8.3.1 to 8.3.2
2020-12-09 08:32:54 +01:00
dependabot[bot]
4dd0a1344e chore(deps): bump uuid from 8.3.1 to 8.3.2
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.3.1 to 8.3.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.3.1...v8.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-09 05:44:32 +00:00
dependabot[bot]
585ead7f24 chore(deps-dev): bump @nestjs/mongoose from 7.1.2 to 7.2.0
Bumps [@nestjs/mongoose](https://github.com/nestjs/mongoose) from 7.1.2 to 7.2.0.
- [Release notes](https://github.com/nestjs/mongoose/releases)
- [Changelog](https://github.com/nestjs/mongoose/blob/master/.release-it.json)
- [Commits](https://github.com/nestjs/mongoose/compare/7.1.2...7.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-09 05:40:49 +00:00
dependabot[bot]
be64b51796 chore(deps-dev): bump @types/node from 14.14.10 to 14.14.11
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.10 to 14.14.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-09 05:32:12 +00:00
dependabot[bot]
55a2efd883 chore(deps-dev): bump @types/mocha from 8.0.4 to 8.2.0
Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 8.0.4 to 8.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-09 05:28:58 +00:00
Renovate Bot
338be4c8d0 chore(deps): update dependency @types/jest to v26.0.18 2020-12-08 21:14:22 +00:00
Christian Allred
b0afb1a63a Merge branch 'master' into master 2020-12-08 13:50:14 -07:00
Christian Allred
59cd40dd56 Revert "fixing option settings in integration tests"
This reverts commit bd988169348670994f2eb3666d78a9a9a1ebfc57.
2020-12-08 13:47:18 -07:00
Christian Allred
685c685bd7 fixing option settings in integration tests 2020-12-08 13:47:13 -07:00
Christian Allred
be2384c4c7 small update 2020-12-08 13:47:02 -07:00
Christian Allred
e7ef9d9c70 Update to Queue Options for rmqlib 2020-12-08 13:47:02 -07:00
Christian Allred
fc5b440da2 updated the typings for rmq socket options to match the interface provided by connection manager 2020-12-08 13:47:02 -07:00
Christian Allred
998d3de9e6 made a dumb copy paste error here. 2020-12-08 13:47:01 -07:00
Christian Allred
e766276922 removing comment 2020-12-08 13:47:01 -07:00
Christian Allred
2abb426d99 added a link for reference 2020-12-08 13:47:01 -07:00
Christian Allred
4fc147f6e0 https://github.com/nestjs/nest/issues/5788 2020-12-08 13:47:01 -07:00
Renovate Bot
63337763a2 fix(deps): pin dependencies 2020-12-08 16:32:49 +00:00
Kamil Myśliwiec
ab6960da62 Merge branch 'master' of https://github.com/nestjs/nest 2020-12-08 17:21:20 +01:00
Kamil Myśliwiec
a0ded7ad68 test(e2e): fix e2e tests 2020-12-08 17:21:13 +01:00
Kamil Mysliwiec
15aca2bfef Merge pull request #5885 from nestjs/chore/update-sample-deps
chore(): update samples dependencies
2020-12-08 14:55:43 +01:00
Kamil Myśliwiec
9df5146082 sample(): downgrade socket.io-redis dep 2020-12-08 14:07:19 +01:00
Kamil Myśliwiec
c79685c88b Merge branch 'master' into chore/update-sample-deps 2020-12-08 14:05:31 +01:00
Kamil Myśliwiec
9c8cf3978a test(): fix promise type arguments (void) 2020-12-08 14:02:25 +01:00
Kamil Myśliwiec
8c9ee77fb8 Merge branch 'mkaufmaner-2984-kafka-reply-partitions' 2020-12-08 13:34:25 +01:00
Kamil Myśliwiec
fb3db3f6bf chore(): minor tweaks, align to the rest of the codebase 2020-12-08 13:34:10 +01:00
Kamil Myśliwiec
8c503d3193 chore(): update typescript to the latest version 2020-12-08 13:27:51 +01:00
Kamil Myśliwiec
b65f1be3f2 Merge branch 'vinayak25-master' 2020-12-08 13:07:20 +01:00
Kamil Myśliwiec
9a64742f61 refactor(core): inline logger condition 2020-12-08 13:07:01 +01:00
Kamil Myśliwiec
1e32627d17 scripts(): only generate package lock (update samples script) 2020-12-08 13:01:48 +01:00
Kamil Myśliwiec
e4243d55c2 Merge branch 'master' of https://github.com/vinayak25/nest into vinayak25-master 2020-12-08 12:59:36 +01:00
Kamil Myśliwiec
684c5f4af7 Merge branch 'master' of https://github.com/nestjs/nest 2020-12-08 12:34:56 +01:00
Kamil Myśliwiec
51e3559995 fix(): fix sse stream unit test 2020-12-08 12:34:51 +01:00
Kamil Myśliwiec
beb8fe36fc chore(): update samples dependencies 2020-12-08 12:31:55 +01:00
Kamil Mysliwiec
2a4dcc1964 Merge pull request #5863 from coder-freestyle/fix-specify-property-name-for-validate-nested
feat(common): specify parent property for validation of nested objects
2020-12-08 11:38:25 +01:00
Kamil Myśliwiec
e7150ba5a9 Merge branch 'miZyind-controller-path-alias' 2020-12-08 11:35:29 +01:00
Karan Gupta
a0a3fb96cf feat(common): specify parent property for validation of nested objects
Passed the complete path of the parent property as an argument. Earlier, the information regarding the parent was getting lost due to flattening of array in case of validation of nested objects.

Closes #5380
2020-12-05 16:13:45 +05:30
Vinayak Sarawagi
7ef474e74e REVERT isNil in applyLogger method 2020-11-30 14:07:13 +05:30
Vinayak Sarawagi
8dc4967721 FIX options.logger bug 2020-11-30 14:02:05 +05:30
Vinayak Sarawagi
419167ad0f fix #5816 2020-11-28 20:17:13 +05:30
Michael Kaufman
35add88251 feat(microservices): Tests for Kafka reply partitioner 2020-11-21 21:24:55 -05:00
Michael Kaufman
0f80068198 feat(microservices): Increase timeout for kafka tests 2020-11-21 20:33:37 -05:00
Michael Kaufman
32b19c7c37 feat(microservices): Uses kafkajs package for tests 2020-11-21 15:13:26 -05:00
Michael Kaufman
827f1e7f77 feat(microservices): Waits for kafka server to close 2020-11-21 14:46:39 -05:00
Michael Kaufman
404a916129 feat(microservices): Fixes dependencies 2020-11-21 14:38:49 -05:00
Michael Kaufman
1e1a52eb20 feat(microservices): Updates package lock 2020-11-21 14:29:46 -05:00
Michael Kaufman
c67b58f527 feat(microservices): Begins updating the reply partitioner test 2020-11-21 14:26:53 -05:00
Michael Kaufman
4763fb9552 feat(microservices): Removes unused exception and updates tests 2020-11-21 14:07:23 -05:00
Michael Kaufman
68ad994f2d feat(microservices): Updates external kafka interface 2020-11-21 13:40:17 -05:00
Michael Kaufman
0f15e35f2b feat(microservices): Removes redundant kafka external interface 2020-11-21 13:32:40 -05:00
Michael Kaufman
25ca219254 feat(microservices): Completed tests for concurrency 2020-11-21 12:50:25 -05:00
Jay McDoniel
525ef91307 feat(microservice): adds tests for custom client proxy 2020-11-17 08:59:45 -08:00
Jay McDoniel
7dad2e479b feat(microservice): allow for custom serialization of data nad error 2020-11-17 07:01:43 -08:00
Jay McDoniel
530274e2c8 feat(microservice): allow for custom ClientProxy implementation 2020-11-17 07:01:42 -08:00
Michael Kaufman
5e21c9e51e feat(microservices): Only stores min partition 2020-11-04 09:40:33 -05:00
Michael Kaufman
b0a0623cf8 feat(microservices): Fixes assigner algo and uses min partition 2020-11-03 16:57:43 -05:00
Michael Kaufman
9449d612aa feat(microservices): Removes assignment store injects client 2020-11-03 09:12:36 -05:00
Michael Kaufman
15473e4251 feat(microservices): Fixes changes to kafka client 2020-11-02 18:49:55 -05:00
Michael Kaufman
1a46de0af3 feat(microservices): Fixes changes to KafkaClient 2020-11-02 18:19:45 -05:00
Michael Kaufman
453e4afd3e feat(microservices): Remove changes that were accidentally included 2020-11-02 18:16:59 -05:00
Michael Kaufman
ffd602ffd5 Merge remote-tracking branch 'Nest/master' into 2984-kafka-reply-partitions 2020-11-02 18:14:55 -05:00
Michael Kaufman
badae7b4e7 feat(microservices): Implement Kafka Nestjs reply partition assigner 2020-11-02 17:55:49 -05:00
gabeodessru
d24d0381a2 sample(12): removed unused module method 2020-11-02 08:45:30 -06:00
Michael Kaufman
a85cb0fe4b feat(microservices): Kafka controller await client consumers connect 2020-10-31 17:39:00 -04:00
Andrei Alecu
cc9a912d0a fix(): add optional dependencies to package.json 2020-10-29 16:07:24 +02:00
gabeodessru
85dcf72508 sample(12): move owner tooling to its own service 2020-06-28 08:59:35 -05:00
gabeodessru
f4df4d9a9e sample(12): Example of how to use @ResolveField 2020-05-23 16:12:38 -05:00
194 changed files with 371318 additions and 210487 deletions

View File

@@ -1,6 +1,6 @@
(The MIT License)
Copyright (c) 2017-2020 Kamil Mysliwiec <https://kamilmysliwiec.com>
Copyright (c) 2017-2021 Kamil Mysliwiec <https://kamilmysliwiec.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
#### Principal Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
<td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
</tr></table>
#### Gold Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td></tr></table>
#### Silver Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
<td align="center" valign="middle">
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
</tr></table>
## Backers

View File

@@ -0,0 +1,177 @@
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import { Test } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
describe('Express Cors', () => {
let app: NestFastifyApplication;
const configs = [
{
origin: 'example.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['foo', 'bar'],
allowedHeaders: ['baz', 'woo'],
maxAge: 123,
},
{
origin: 'sample.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['zoo', 'bar'],
allowedHeaders: ['baz', 'foo'],
maxAge: 321,
},
];
describe('Dynamic config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app.enableCors(configDelegation);
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configDelegation,
});
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
describe('Static config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
app.enableCors(configs[0]);
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configs[0],
});
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
});

View File

@@ -0,0 +1,177 @@
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import { Test } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
describe('Fastify Cors', () => {
let app: NestFastifyApplication;
const configs = [
{
origin: 'example.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['foo', 'bar'],
allowedHeaders: ['baz', 'woo'],
maxAge: 123,
},
{
origin: 'sample.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['zoo', 'bar'],
allowedHeaders: ['baz', 'foo'],
maxAge: 321,
},
];
describe('Dynamic config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app.enableCors(configDelegation);
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configDelegation,
});
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
describe('Static config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
app.enableCors(configs[0]);
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configs[0],
});
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
});
});

View File

@@ -0,0 +1,9 @@
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
getGlobals() {
return '';
}
}

View File

@@ -0,0 +1,7 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
controllers: [AppController],
})
export class AppModule {}

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"allowJs": true,
"outDir": "./dist"
},
"include": [
"src/**/*",
"e2e/**/*"
],
"exclude": [
"node_modules",
]
}

View File

@@ -23,7 +23,7 @@ services:
- "9001:9001"
restart: always
mysql:
image: mysql:5.7.32
image: mysql:5.7.33
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
@@ -48,7 +48,7 @@ services:
zookeeper:
container_name: test-zookeeper
hostname: zookeeper
image: confluentinc/cp-zookeeper:5.5.2
image: confluentinc/cp-zookeeper:5.5.3
ports:
- "2181:2181"
environment:
@@ -57,7 +57,7 @@ services:
kafka:
container_name: test-kafka
hostname: kafka
image: confluentinc/cp-kafka:5.5.2
image: confluentinc/cp-kafka:5.5.3
depends_on:
- zookeeper
ports:
@@ -70,3 +70,4 @@ services:
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_DELETE_TOPIC_ENABLE: 'true'

View File

@@ -63,6 +63,22 @@ describe('Hello world (fastify adapter)', () => {
});
});
it(`/GET { host: [":tenant.example1.com", ":tenant.example2.com"] } not matched`, () => {
return app
.inject({
method: 'GET',
url: '/host-array',
})
.then(({ payload }) => {
expect(JSON.parse(payload)).to.be.eql({
error: 'Internal Server Error',
message:
'HTTP adapter does not support filtering on hosts: [":tenant.example1.com", ":tenant.example2.com"]',
statusCode: 500,
});
});
});
it(`/GET inject with LightMyRequest chaining API`, () => {
return app
.inject()

View File

@@ -28,6 +28,16 @@ describe('Hello world (default adapter)', () => {
path: '/host',
greeting: 'Host Greeting! tenant=acme',
},
{
host: 'acme.example1.com',
path: '/host-array',
greeting: 'Host Greeting! tenant=acme',
},
{
host: 'acme.example2.com',
path: '/host-array',
greeting: 'Host Greeting! tenant=acme',
},
].forEach(({ host, path, greeting }) => {
describe(`host=${host}`, () => {
describe('/GET', () => {

View File

@@ -1,8 +1,9 @@
import { Module } from '@nestjs/common';
import { HelloModule } from './hello/hello.module';
import { HostArrayModule } from './host-array/host-array.module';
import { HostModule } from './host/host.module';
@Module({
imports: [HelloModule, HostModule],
imports: [HelloModule, HostModule, HostArrayModule],
})
export class ApplicationModule {}

View File

@@ -0,0 +1,10 @@
import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
export class TestDto {
@IsString()
@IsNotEmpty()
string: string;
@IsNumber()
number: number;
}

View File

@@ -0,0 +1,37 @@
import { Controller, Get, Header, HostParam, Param } from '@nestjs/common';
import { Observable, of } from 'rxjs';
import { HostArrayService } from './host-array.service';
import { UserByIdPipe } from './users/user-by-id.pipe';
@Controller({
path: 'host-array',
host: [':tenant.example1.com', ':tenant.example2.com'],
})
export class HostArrayController {
constructor(private readonly hostService: HostArrayService) {}
@Get()
@Header('Authorization', 'Bearer')
greeting(@HostParam('tenant') tenant: string): string {
return `${this.hostService.greeting()} tenant=${tenant}`;
}
@Get('async')
async asyncGreeting(@HostParam('tenant') tenant: string): Promise<string> {
return `${await this.hostService.greeting()} tenant=${tenant}`;
}
@Get('stream')
streamGreeting(@HostParam('tenant') tenant: string): Observable<string> {
return of(`${this.hostService.greeting()} tenant=${tenant}`);
}
@Get('local-pipe/:id')
localPipe(
@Param('id', UserByIdPipe)
user: any,
@HostParam('tenant') tenant: string,
): any {
return { ...user, tenant };
}
}

View File

@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { HostArrayController } from './host-array.controller';
import { HostArrayService } from './host-array.service';
import { UsersService } from './users/users.service';
@Module({
controllers: [HostArrayController],
providers: [HostArrayService, UsersService],
})
export class HostArrayModule {}

View File

@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class HostArrayService {
greeting(): string {
return 'Host Greeting!';
}
}

View File

@@ -0,0 +1,11 @@
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
import { UsersService } from './users.service';
@Injectable()
export class UserByIdPipe implements PipeTransform<string> {
constructor(private readonly usersService: UsersService) {}
transform(value: string, metadata: ArgumentMetadata) {
return this.usersService.findById(value);
}
}

View File

@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
findById(id: string) {
return { id, host: true };
}
}

View File

@@ -26,7 +26,7 @@ class TestInjectable
class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule, { logger: true });
const app = await NestFactory.create(AppModule, { logger: false });
if (SIGNAL_TO_LISTEN && SIGNAL_TO_LISTEN !== 'NONE') {
app.enableShutdownHooks([SIGNAL_TO_LISTEN]);

View File

@@ -0,0 +1,291 @@
import { INestApplication, Logger } from '@nestjs/common';
import { Transport } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import { Admin, ITopicMetadata, Kafka } from 'kafkajs';
import * as request from 'supertest';
import * as util from 'util';
import { KafkaConcurrentController } from '../src/kafka-concurrent/kafka-concurrent.controller';
import { KafkaConcurrentMessagesController } from '../src/kafka-concurrent/kafka-concurrent.messages.controller';
describe('Kafka concurrent', function () {
const numbersOfServers = 3;
const requestTopic = 'math.sum.sync.number.wait';
const responseTopic = 'math.sum.sync.number.wait.reply';
let admin: Admin;
const servers: any[] = [];
const apps: INestApplication[] = [];
const logger = new Logger('concurrent-kafka.spec.ts');
// set timeout to be longer (especially for the after hook)
this.timeout(30000);
const startServer = async () => {
const module = await Test.createTestingModule({
controllers: [
KafkaConcurrentController,
KafkaConcurrentMessagesController,
],
}).compile();
// use our own logger for a little
// Logger.overrideLogger(new Logger());
const app = module.createNestApplication();
const server = app.getHttpAdapter().getInstance();
app.connectMicroservice({
transport: Transport.KAFKA,
options: {
client: {
brokers: ['localhost:9092'],
},
run: {
partitionsConsumedConcurrently: numbersOfServers,
},
},
});
// enable these for clean shutdown
app.enableShutdownHooks();
// push to the collection
servers.push(server);
apps.push(app);
// await the start
await app.startAllMicroservicesAsync();
await app.init();
};
it(`Create kafka topics/partitions`, async () => {
const kafka = new Kafka({
clientId: 'concurrent-test-admin',
brokers: ['localhost:9092'],
});
admin = kafka.admin();
await admin.connect();
let topicMetadata: {
topics: ITopicMetadata[];
};
try {
topicMetadata = await admin.fetchTopicMetadata({
topics: [requestTopic, responseTopic],
});
} catch (e) {
// create with number of servers
try {
await admin.createTopics({
topics: [
{
topic: requestTopic,
numPartitions: numbersOfServers,
replicationFactor: 1,
},
{
topic: responseTopic,
numPartitions: numbersOfServers,
replicationFactor: 1,
},
],
});
} catch (e) {
logger.error(util.format('Create topics error: %o', e));
}
}
if (topicMetadata && topicMetadata.topics.length > 0) {
// we have topics, how many partitions do they have?
for (const topic of topicMetadata.topics) {
if (topic.partitions.length < numbersOfServers) {
try {
await admin.createPartitions({
topicPartitions: [
{
topic: topic.name,
count: numbersOfServers,
},
],
});
} catch (e) {
logger.error(util.format('Create partitions error: %o', e));
}
}
}
}
// create with number of servers
try {
await admin.createTopics({
topics: [
{
topic: requestTopic,
numPartitions: numbersOfServers,
replicationFactor: 1,
},
{
topic: responseTopic,
numPartitions: numbersOfServers,
replicationFactor: 1,
},
],
});
} catch (e) {
logger.error(util.format('Create topics error: %o', e));
}
// disconnect
await admin.disconnect();
});
it(`Start Kafka apps`, async () => {
// start all at once
await Promise.all(
Array(numbersOfServers)
.fill(1)
.map(async (v, i) => {
// return startServer();
// wait in intervals so the consumers start in order
return new Promise<void>(resolve => {
setTimeout(async () => {
await startServer();
return resolve();
}, 1000 * i);
});
}),
);
}).timeout(30000);
it(`Concurrent messages without forcing a rebalance.`, async () => {
// wait a second before notifying the servers to respond
setTimeout(async () => {
// notify the other servers that it is time to respond
await Promise.all(
servers.map(async server => {
// send to all servers since indexes don't necessarily align with server consumers
return request(server).post('/go').send();
}),
);
}, 1000);
await Promise.all(
servers.map(async (server, index) => {
// send requests
const payload = {
key: index,
numbers: [1, index],
};
const result = (1 + index).toString();
return request(server)
.post('/mathSumSyncNumberWait')
.send(payload)
.expect(200)
.expect(200, result);
}),
);
});
it(`Close kafka client consumer while waiting for message pattern response.`, async () => {
await Promise.all(
servers.map(async (server, index) => {
// shut off and delete the leader
if (index === 0) {
return new Promise<void>(resolve => {
// wait a second before closing so the producers can send the message to the server consumers
setTimeout(async () => {
// get the controller
const controller = apps[index].get(KafkaConcurrentController);
// close the controller clients
await controller.client.close();
// notify the other servers that we have stopped
await Promise.all(
servers.map(async server => {
// send to all servers since indexes don't necessarily align with server consumers
return request(server).post('/go').send();
}),
);
return resolve();
}, 1000);
});
}
// send requests
const payload = {
key: index,
numbers: [1, index],
};
const result = (1 + index).toString();
return request(server)
.post('/mathSumSyncNumberWait')
.send(payload)
.expect(200)
.expect(200, result);
}),
);
});
it(`Start kafka client consumer while waiting for message pattern response.`, async () => {
await Promise.all(
servers.map(async (server, index) => {
// shut off and delete the leader
if (index === 0) {
return new Promise<void>(resolve => {
// wait a second before closing so the producers can send the message to the server consumers
setTimeout(async () => {
// get the controller
const controller = apps[index].get(KafkaConcurrentController);
// connect the controller client
await controller.client.connect();
// notify the servers that we have started
await Promise.all(
servers.map(async server => {
// send to all servers since indexes don't necessarily align with server consumers
return request(server).post('/go').send();
}),
);
return resolve();
}, 1000);
});
}
// send requests
const payload = {
key: index,
numbers: [1, index],
};
const result = (1 + index).toString();
return request(server)
.post('/mathSumSyncNumberWait')
.send(payload)
.expect(200)
.expect(200, result);
}),
);
});
after(`Stopping Kafka app`, async () => {
// close all concurrently
return Promise.all(
apps.map(async app => {
return app.close();
}),
);
});
});

View File

@@ -9,10 +9,13 @@ import { UserEntity } from '../src/kafka/entities/user.entity';
import { KafkaController } from '../src/kafka/kafka.controller';
import { KafkaMessagesController } from '../src/kafka/kafka.messages.controller';
describe('Kafka transport', () => {
describe('Kafka transport', function () {
let server;
let app: INestApplication;
// set timeout to be longer (especially for the after hook)
this.timeout(30000);
it(`Start Kafka app`, async () => {
const module = await Test.createTestingModule({
controllers: [KafkaController, KafkaMessagesController],
@@ -29,6 +32,7 @@ describe('Kafka transport', () => {
},
},
});
app.enableShutdownHooks();
await app.startAllMicroservicesAsync();
await app.init();
}).timeout(30000);

View File

@@ -105,6 +105,22 @@ describe('RPC transport', () => {
});
});
it('/POST (custom client)', () => {
return request(server)
.post('/error?client=custom')
.send({})
.expect(200)
.expect('true');
});
it('/POST (standard client)', () => {
return request(server)
.post('/error?client=standard')
.send({})
.expect(200)
.expect('false');
});
afterEach(async () => {
await app.close();
});

View File

@@ -12,15 +12,17 @@ import {
EventPattern,
MessagePattern,
Transport,
RpcException,
} from '@nestjs/microservices';
import { from, Observable, of } from 'rxjs';
import { scan } from 'rxjs/operators';
import { from, Observable, of, throwError } from 'rxjs';
import { catchError, scan } from 'rxjs/operators';
@Controller()
export class AppController {
constructor(
@Inject('USE_CLASS_CLIENT') private useClassClient: ClientProxy,
@Inject('USE_FACTORY_CLIENT') private useFactoryClient: ClientProxy,
@Inject('CUSTOM_PROXY_CLIENT') private customClient: ClientProxy,
) {}
static IS_NOTIFIED = false;
@@ -75,6 +77,17 @@ export class AppController {
.reduce(async (a, b) => (await a) && b);
}
@Post('error')
@HttpCode(200)
serializeError(@Query('client') query: 'custom' | 'standard' = 'standard', @Body() body: Record<string, any>): Observable<boolean> {
const client = query === 'custom' ? this.customClient : this.client;
return client.send({ cmd: 'err' }, {}).pipe(
catchError((err) => {
return of(err instanceof RpcException);
})
)
}
@MessagePattern({ cmd: 'sum' })
sum(data: number[]): number {
return (data || []).reduce((a, b) => a + b);
@@ -95,6 +108,11 @@ export class AppController {
return from(data);
}
@MessagePattern({ cmd: 'err' })
throwAnError() {
return throwError(new Error('err'));
}
@Post('notify')
async sendNotification(): Promise<any> {
return this.client.emit<number>('notification', true);

View File

@@ -5,8 +5,16 @@ import {
Transport,
ClientsModuleOptionsFactory,
ClientOptions,
ClientTCP,
RpcException,
} from '@nestjs/microservices';
class ErrorHandlingProxy extends ClientTCP {
serializeError(err) {
return new RpcException(err);
}
}
@Injectable()
class ConfigService {
private readonly config = {
@@ -51,7 +59,14 @@ class ClientOptionService implements ClientsModuleOptionsFactory {
name: 'USE_CLASS_CLIENT',
useClass: ClientOptionService,
inject: [ConfigService],
},
}, {
imports: [ConfigModule],
inject: [ConfigService],
name: 'CUSTOM_PROXY_CLIENT',
useFactory: (config: ConfigService) => ({
customClass: ErrorHandlingProxy
})
}
]),
],
controllers: [AppController],

View File

@@ -0,0 +1,4 @@
export class SumDto {
key: string;
numbers: number[];
}

View File

@@ -0,0 +1,70 @@
import {
Body,
Controller,
HttpCode,
OnModuleDestroy,
OnModuleInit,
Post,
} from '@nestjs/common';
import { Logger } from '@nestjs/common/services/logger.service';
import { Client, ClientKafka, Transport } from '@nestjs/microservices';
import { PartitionerArgs } from 'kafkajs';
import { Observable } from 'rxjs';
import { SumDto } from './dto/sum.dto';
/**
* The following function explicity sends messages to the key representing the partition.
*/
const explicitPartitioner = () => {
return ({ message }: PartitionerArgs) => {
return parseFloat(message.headers.toPartition.toString());
};
};
@Controller()
export class KafkaConcurrentController
implements OnModuleInit, OnModuleDestroy {
protected readonly logger = new Logger(KafkaConcurrentController.name);
@Client({
transport: Transport.KAFKA,
options: {
client: {
brokers: ['localhost:9092'],
},
run: {
partitionsConsumedConcurrently: 3,
},
producer: {
createPartitioner: explicitPartitioner,
},
},
})
public readonly client: ClientKafka;
async onModuleInit() {
const requestPatterns = ['math.sum.sync.number.wait'];
requestPatterns.forEach(pattern => {
this.client.subscribeToResponseOf(pattern);
});
await this.client.connect();
}
async onModuleDestroy() {
await this.client.close();
}
@Post('mathSumSyncNumberWait')
@HttpCode(200)
public mathSumSyncNumberWait(@Body() data: SumDto): Observable<string> {
return this.client.send('math.sum.sync.number.wait', {
headers: {
toPartition: data.key.toString(),
},
key: data.key.toString(),
value: data.numbers,
});
}
}

View File

@@ -0,0 +1,37 @@
import { Controller, HttpCode, Post } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import { BehaviorSubject, Observable } from 'rxjs';
import { first, map, skipWhile } from 'rxjs/operators';
@Controller()
export class KafkaConcurrentMessagesController {
public waiting = new BehaviorSubject<boolean>(false);
@Post('go')
@HttpCode(200)
async go() {
// no longer waiting
this.waiting.next(false);
return;
}
@MessagePattern('math.sum.sync.number.wait')
public mathSumSyncNumberWait(data: any): Observable<number> {
// start waiting
this.waiting.next(true);
// find sum
const sum = data.value[0] + data.value[1];
return this.waiting.asObservable().pipe(
skipWhile(isWaiting => {
return isWaiting;
}),
map(() => {
return sum;
}),
first(),
);
}
}

View File

@@ -1,4 +1,11 @@
import { Body, Controller, HttpCode, OnModuleInit, Post } from '@nestjs/common';
import {
Body,
Controller,
HttpCode,
OnModuleInit,
Post,
OnModuleDestroy,
} from '@nestjs/common';
import { Logger } from '@nestjs/common/services/logger.service';
import { Client, ClientKafka, Transport } from '@nestjs/microservices';
import { Observable } from 'rxjs';
@@ -6,7 +13,7 @@ import { BusinessDto } from './dtos/business.dto';
import { UserDto } from './dtos/user.dto';
@Controller()
export class KafkaController implements OnModuleInit {
export class KafkaController implements OnModuleInit, OnModuleDestroy {
protected readonly logger = new Logger(KafkaController.name);
static IS_NOTIFIED = false;
static MATH_SUM = 0;
@@ -21,7 +28,7 @@ export class KafkaController implements OnModuleInit {
})
private readonly client: ClientKafka;
onModuleInit() {
async onModuleInit() {
const requestPatterns = [
'math.sum.sync.kafka.message',
'math.sum.sync.without.key',
@@ -36,6 +43,12 @@ export class KafkaController implements OnModuleInit {
requestPatterns.forEach(pattern => {
this.client.subscribeToResponseOf(pattern);
});
await this.client.connect();
}
async onModuleDestroy() {
await this.client.close();
}
// sync send kafka message

View File

@@ -20,7 +20,7 @@ describe('ErrorGateway', () => {
ws.emit('push', {
test: 'test',
});
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('exception', data => {
expect(data).to.be.eql({
status: 'error',

View File

@@ -20,7 +20,7 @@ describe('WebSocketGateway (ack)', () => {
await app.listenAsync(3000);
ws = io.connect('http://localhost:8080');
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.emit('push', { test: 'test' }, data => {
expect(data).to.be.eql('pong');
resolve();
@@ -33,7 +33,7 @@ describe('WebSocketGateway (ack)', () => {
await app.listenAsync(3000);
ws = io.connect('http://localhost:8080');
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.emit('push', data => {
expect(data).to.be.eql('pong');
resolve();

View File

@@ -25,7 +25,7 @@ describe('WebSocketGateway', () => {
ws.emit('push', {
test: 'test',
});
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('pop', data => {
expect(data.test).to.be.eql('test');
resolve();
@@ -41,7 +41,7 @@ describe('WebSocketGateway', () => {
ws.emit('push', {
test: 'test',
});
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('pop', data => {
expect(data.test).to.be.eql('test');
resolve();
@@ -58,7 +58,7 @@ describe('WebSocketGateway', () => {
ws.emit('push', {
test: 'test',
});
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('pop', data => {
expect(data.test).to.be.eql('test');
resolve();

View File

@@ -34,7 +34,7 @@ describe('WebSocketGateway (WsAdapter)', () => {
},
}),
);
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('message', data => {
expect(JSON.parse(data).data.test).to.be.eql('test');
resolve();
@@ -57,7 +57,7 @@ describe('WebSocketGateway (WsAdapter)', () => {
},
}),
);
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('message', data => {
expect(JSON.parse(data).data.test).to.be.eql('test');
resolve();
@@ -77,7 +77,7 @@ describe('WebSocketGateway (WsAdapter)', () => {
ws = new WebSocket('ws://localhost:8080');
ws2 = new WebSocket('ws://localhost:8090');
await new Promise(resolve =>
await new Promise<void>(resolve =>
ws.on('open', () => {
ws.on('message', data => {
expect(JSON.parse(data).data.test).to.be.eql('test');
@@ -94,7 +94,7 @@ describe('WebSocketGateway (WsAdapter)', () => {
}),
);
await new Promise(resolve => {
await new Promise<void>(resolve => {
ws2.on('message', data => {
expect(JSON.parse(data).data.test).to.be.eql('test');
resolve();

View File

@@ -3,5 +3,5 @@
"packages": [
"packages/*"
],
"version": "7.5.5"
"version": "7.6.10"
}

2586
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/core",
"version": "7.5.3",
"version": "7.6.8",
"description": "Modern, fast, powerful node.js web framework",
"homepage": "https://nestjs.com",
"repository": {
@@ -29,9 +29,10 @@
"test:docker:up": "docker-compose -f integration/docker-compose.yml up -d",
"test:docker:down": "docker-compose -f integration/docker-compose.yml down",
"lint": "concurrently 'npm run lint:packages' 'npm run lint:integration' 'npm run lint:spec'",
"lint:integration": "eslint 'integration/*/{,!(node_modules)/**/}/*.ts' -c '.eslintrc.spec.js' --fix",
"lint:packages": "eslint 'packages/**/**.ts' --fix --ignore-pattern 'packages/**/*.spec.ts'",
"lint:spec": "eslint 'packages/**/**.spec.ts' -c '.eslintrc.spec.js' --fix",
"lint:fix": "concurrently 'npm run lint:packages -- --fix' 'npm run lint:integration -- --fix' 'npm run lint:spec -- --fix'",
"lint:integration": "eslint 'integration/*/{,!(node_modules)/**/}/*.ts' -c '.eslintrc.spec.js'",
"lint:packages": "eslint 'packages/**/**.ts' --ignore-pattern 'packages/**/*.spec.ts'",
"lint:spec": "eslint 'packages/**/**.spec.ts' -c '.eslintrc.spec.js'",
"prerelease": "gulp copy-misc && gulp build --dist node_modules/@nestjs",
"publish": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --force-publish --access public --exact -m \"chore(@nestjs) publish %s release\"",
"publish:beta": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --npm-tag=beta --access public -m \"chore(@nestjs) publish %s release\"",
@@ -52,52 +53,52 @@
},
"dependencies": {
"@nuxtjs/opencollective": "0.3.2",
"axios": "0.21.0",
"class-transformer": "0.3.1",
"class-validator": "0.12.2",
"axios": "0.21.1",
"class-transformer": "0.3.2",
"class-validator": "0.13.1",
"cli-color": "2.0.0",
"cors": "2.8.5",
"express": "4.17.1",
"fast-json-stringify": "2.2.10",
"fast-json-stringify": "2.4.1",
"fast-safe-stringify": "2.0.7",
"iterare": "1.2.1",
"object-hash": "2.0.3",
"object-hash": "2.1.1",
"path-to-regexp": "3.2.0",
"reflect-metadata": "0.1.13",
"rxjs": "6.6.3",
"socket.io": "2.3.0",
"uuid": "8.3.1",
"tslib": "2.0.3"
"socket.io": "2.4.1",
"tslib": "2.1.0",
"uuid": "8.3.2"
},
"devDependencies": {
"@codechecks/client": "0.1.10",
"@commitlint/cli": "11.0.0",
"@commitlint/config-angular": "11.0.0",
"@grpc/proto-loader": "0.5.5",
"@nestjs/graphql": "7.9.1",
"@nestjs/mongoose": "7.1.2",
"@grpc/proto-loader": "0.5.6",
"@nestjs/graphql": "7.9.8",
"@nestjs/mongoose": "7.2.2",
"@nestjs/typeorm": "7.1.5",
"@types/amqplib": "0.5.16",
"@types/amqplib": "0.5.17",
"@types/bytes": "3.1.0",
"@types/cache-manager": "2.10.3",
"@types/cache-manager": "3.4.0",
"@types/chai": "4.2.14",
"@types/chai-as-promised": "7.1.3",
"@types/cors": "2.8.8",
"@types/express": "4.17.9",
"@types/gulp": "4.0.7",
"@types/mocha": "8.0.4",
"@types/mongoose": "5.10.2",
"@types/node": "14.14.10",
"@types/cors": "2.8.9",
"@types/express": "4.17.11",
"@types/gulp": "4.0.8",
"@types/mocha": "8.2.0",
"@types/mongoose": "5.10.3",
"@types/node": "14.14.22",
"@types/redis": "2.8.28",
"@types/reflect-metadata": "0.1.0",
"@types/sinon": "9.0.9",
"@types/socket.io": "2.1.12",
"@types/sinon": "9.0.10",
"@types/socket.io": "2.1.13",
"@types/ws": "7.4.0",
"@typescript-eslint/eslint-plugin": "4.9.1",
"@typescript-eslint/parser": "4.9.0",
"@typescript-eslint/eslint-plugin": "4.14.2",
"@typescript-eslint/parser": "4.14.2",
"amqp-connection-manager": "3.2.1",
"amqplib": "0.6.0",
"apollo-server-express": "2.19.0",
"apollo-server-express": "2.19.2",
"artillery": "1.6.1",
"awesome-typescript-loader": "5.2.1",
"body-parser": "1.19.0",
@@ -105,25 +106,25 @@
"cache-manager": "3.4.0",
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
"clang-format": "1.4.0",
"clang-format": "1.5.0",
"commitlint-circle": "1.0.0",
"concurrently": "5.3.0",
"conventional-changelog": "3.1.24",
"core-js": "3.8.1",
"core-js": "3.8.3",
"coveralls": "3.1.0",
"delete-empty": "3.0.0",
"engine.io-client": "4.0.4",
"eslint": "7.15.0",
"eslint-config-prettier": "7.0.0",
"engine.io-client": "4.1.1",
"eslint": "7.19.0",
"eslint-config-prettier": "7.2.0",
"eslint-plugin-import": "2.22.1",
"eventsource": "1.0.7",
"fancy-log": "1.3.3",
"fastify": "3.9.1",
"fastify-cors": "5.0.0",
"fastify": "3.11.0",
"fastify-cors": "5.2.0",
"fastify-formbody": "5.0.0",
"fastify-multipart": "3.3.1",
"fastify-static": "3.3.0",
"graphql": "15.4.0",
"fastify-static": "3.4.0",
"graphql": "15.5.0",
"graphql-tools": "7.0.2",
"grpc": "1.24.4",
"gulp": "4.0.2",
@@ -132,39 +133,39 @@
"gulp-sourcemaps": "3.0.0",
"gulp-typescript": "5.0.1",
"gulp-watch": "5.0.1",
"husky": "4.3.5",
"imports-loader": "1.2.0",
"husky": "4.3.8",
"imports-loader": "2.0.0",
"json-loader": "0.5.7",
"kafkajs": "1.12.0",
"kafkajs": "1.15.0",
"lerna": "2.11.0",
"light-my-request": "4.3.0",
"light-my-request": "4.4.1",
"lint-staged": "10.5.3",
"markdown-table": "2.0.0",
"merge-graphql-schemas": "1.7.8",
"middie": "5.2.0",
"mocha": "8.2.1",
"mongoose": "5.11.5",
"mongoose": "5.11.14",
"mqtt": "4.2.6",
"multer": "1.4.2",
"mysql": "2.18.1",
"nats": "1.4.12",
"nodemon": "2.0.6",
"nodemon": "2.0.7",
"nyc": "15.1.0",
"point-of-view": "4.7.0",
"point-of-view": "4.11.0",
"prettier": "2.2.1",
"redis": "3.0.2",
"rxjs-compat": "6.6.3",
"sinon": "9.2.1",
"sinon": "9.2.4",
"sinon-chai": "3.5.0",
"socket.io-client": "2.3.1",
"socket.io-client": "2.4.0",
"subscriptions-transport-ws": "0.9.18",
"supertest": "6.0.1",
"supertest": "6.1.3",
"ts-morph": "9.1.0",
"ts-node": "9.1.1",
"typeorm": "0.2.29",
"typescript": "4.0.3",
"typeorm": "0.2.30",
"typescript": "4.1.3",
"wrk": "1.2.1",
"ws": "7.4.1"
"ws": "7.4.3"
},
"engines": {
"node": ">= 10.13.0"

View File

@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
#### Principal Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
<td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
</tr></table>
#### Gold Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td></tr></table>
#### Silver Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
<td align="center" valign="middle">
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
</tr></table>
## Backers

View File

@@ -27,7 +27,7 @@ export interface ControllerOptions extends ScopeOptions {
*
* @see [Routing](https://docs.nestjs.com/controllers#routing)
*/
host?: string;
host?: string | string[];
}
/**

View File

@@ -78,4 +78,3 @@ export class HttpException extends Error {
: { statusCode, message: objectOrError, error: description };
}
}

View File

@@ -50,4 +50,9 @@ export interface ClassTransformOptions {
* and exposing all class properties (with undefined, if nothing else is given)
*/
excludeExtraneousValues?: boolean;
/**
* If set to true then class transformer will take default values for unprovided fields.
* This is useful when you convert a plain object to a class and have an optional field with a default value.
*/
exposeDefaultValues?: boolean;
}

View File

@@ -52,3 +52,10 @@ export interface CorsOptions {
*/
optionsSuccessStatus?: number;
}
export interface CorsOptionsCallback {
(error: Error, options: CorsOptions): void;
}
export interface CorsOptionsDelegate<T> {
(req: T, cb: CorsOptionsCallback): void;
}

View File

@@ -2,29 +2,41 @@
* Validation error description.
* @see https://github.com/typestack/class-validator
*
* class-validator@0.13.0
*
* @publicApi
*/
export interface ValidationError {
/**
* Object that was validated.
*
* OPTIONAL - configurable via the ValidatorOptions.validationError.target option
*/
target: Record<string, any>;
target?: Record<string, any>;
/**
* Object's property that hasn't passed validation.
*/
property: string;
/**
* Value that hasn't passed validation.
* Value that haven't pass a validation.
*
* OPTIONAL - configurable via the ValidatorOptions.validationError.value option
*/
value: any;
value?: any;
/**
* Constraints that failed validation with error messages.
*/
constraints: {
constraints?: {
[type: string]: string;
};
/**
* Contains all nested validation errors of the property.
*/
children: ValidationError[];
children?: ValidationError[];
/**
* A transient set of data passed through to the validation result for response mapping
*/
contexts?: {
[type: string]: any;
};
}

View File

@@ -2,11 +2,15 @@
* Options passed to validator during validation.
* @see https://github.com/typestack/class-validator
*
* class-validator@0.10.1
* class-validator@0.13.0
*
* @publicApi
*/
export interface ValidatorOptions {
/**
* If set to true then class-validator will print extra warning messages to the console when something is not right.
*/
enableDebugMessages?: boolean;
/**
* If set to true then validator will skip validation of all properties that are undefined in the validating object.
*/
@@ -33,6 +37,15 @@ export interface ValidatorOptions {
* Groups to be used during validation of the object.
*/
groups?: string[];
/**
* Set default for `always` option of decorators. Default can be overridden in decorator options.
*/
always?: boolean;
/**
* If [groups]{@link ValidatorOptions#groups} is not given or is empty,
* ignore decorators with at least one group.
*/
strictGroups?: boolean;
/**
* If set to true, the validation will not use default messages.
* Error message always will be undefined if its not explicitly set.
@@ -55,4 +68,8 @@ export interface ValidatorOptions {
* Settings true will cause fail validation of unknown objects.
*/
forbidUnknownValues?: boolean;
/**
* When set to true, validation of the given property will stop after encountering the first error. Defaults to false.
*/
stopAtFirstError?: boolean;
}

View File

@@ -1,5 +1,8 @@
import { RequestMethod } from '../../enums';
import { CorsOptions } from '../../interfaces/external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from '../../interfaces/external/cors-options.interface';
import { NestApplicationOptions } from '../../interfaces/nest-application-options.interface';
export type ErrorHandler<TRequest = any, TResponse = any> = (
@@ -62,7 +65,7 @@ export interface HttpServer<TRequest = any, TResponse = any> {
getRequestUrl?(request: TResponse): string;
getInstance(): any;
registerParserMiddleware(): any;
enableCors(options: CorsOptions): any;
enableCors(options: CorsOptions | CorsOptionsDelegate<TRequest>): any;
getHttpServer(): any;
initHttpServer(options: NestApplicationOptions): void;
close(): any;

View File

@@ -1,6 +1,7 @@
import { ShutdownSignal } from '../enums/shutdown-signal.enum';
import { LoggerService, LogLevel } from '../services/logger.service';
import { Abstract } from './abstract.interface';
import { DynamicModule } from './modules';
import { Type } from './type.interface';
/**
@@ -13,7 +14,7 @@ export interface INestApplicationContext {
* Allows navigating through the modules tree, for example, to pull out a specific instance from the selected module.
* @returns {INestApplicationContext}
*/
select<T>(module: Type<T>): INestApplicationContext;
select<T>(module: Type<T> | DynamicModule): INestApplicationContext;
/**
* Retrieves an instance of either injectable or controller, otherwise, throws exception.

View File

@@ -1,4 +1,7 @@
import { CorsOptions } from './external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from './external/cors-options.interface';
import { HttpsOptions } from './external/https-options.interface';
import { NestApplicationContextOptions } from './nest-application-context-options.interface';
@@ -9,7 +12,7 @@ export interface NestApplicationOptions extends NestApplicationContextOptions {
/**
* CORS options from [CORS package](https://github.com/expressjs/cors#configuration-options)
*/
cors?: boolean | CorsOptions;
cors?: boolean | CorsOptions | CorsOptionsDelegate<any>;
/**
* Whether to use underlying platform body parser.
*/

View File

@@ -1,4 +1,7 @@
import { CorsOptions } from './external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from './external/cors-options.interface';
import { CanActivate } from './features/can-activate.interface';
import { NestInterceptor } from './features/nest-interceptor.interface';
import { HttpServer } from './http/http-server.interface';
@@ -30,7 +33,7 @@ export interface INestApplication extends INestApplicationContext {
*
* @returns {void}
*/
enableCors(options?: CorsOptions): void;
enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void;
/**
* Starts the application.

View File

@@ -1,3 +1,3 @@
export interface Type<T> extends Function {
export interface Type<T = any> extends Function {
new (...args: any[]): T;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/common",
"version": "7.5.5",
"version": "7.6.10",
"description": "Nest - modern, fast, powerful node.js web framework (@common)",
"author": "Kamil Mysliwiec",
"homepage": "https://nestjs.com",
@@ -17,13 +17,27 @@
},
"license": "MIT",
"dependencies": {
"axios": "0.21.0",
"axios": "0.21.1",
"iterare": "1.2.1",
"tslib": "2.0.3",
"uuid": "8.3.1"
"tslib": "2.1.0",
"uuid": "8.3.2"
},
"peerDependencies": {
"cache-manager": "*",
"class-transformer": "*",
"class-validator": "*",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0"
},
"peerDependenciesMeta": {
"cache-manager": {
"optional": true
},
"class-validator": {
"optional": true
},
"class-transformer": {
"optional": true
}
}
}

View File

@@ -86,7 +86,39 @@ export class ParseArrayPipe implements PipeTransform {
} catch {}
return this.validationPipe.transform(item, validationMetadata);
};
value = await Promise.all(value.map(toClassInstance));
if (this.options.stopAtFirstError === false) {
// strict compare to "false" to make sure
// that this option is disabled by default
let errors = [];
const targetArray = value as Array<unknown>;
for (let i = 0; i < targetArray.length; i++) {
try {
targetArray[i] = await toClassInstance(targetArray[i]);
} catch (err) {
let message: string[] | unknown;
if (err.getResponse) {
const response = err.getResponse();
if (Array.isArray(response.message)) {
message = response.message.map(
(item: string) => `[${i}] ${item}`,
);
} else {
message = `[${i}] ${response.message}`;
}
} else {
message = err;
}
errors = errors.concat(message);
}
}
if (errors.length > 0) {
throw this.exceptionFactory(errors as any);
}
return targetArray;
} else {
value = await Promise.all(value.map(toClassInstance));
}
}
return value;
}

View File

@@ -199,27 +199,35 @@ export class ValidationPipe implements PipeTransform<any> {
protected mapChildrenToValidationErrors(
error: ValidationError,
parentPath?: string,
): ValidationError[] {
if (!(error.children && error.children.length)) {
return [error];
}
const validationErrors = [];
parentPath = parentPath
? `${parentPath}.${error.property}`
: error.property;
for (const item of error.children) {
if (item.children && item.children.length) {
validationErrors.push(...this.mapChildrenToValidationErrors(item));
validationErrors.push(
...this.mapChildrenToValidationErrors(item, parentPath),
);
}
validationErrors.push(this.prependConstraintsWithParentProp(error, item));
validationErrors.push(
this.prependConstraintsWithParentProp(parentPath, item),
);
}
return validationErrors;
}
protected prependConstraintsWithParentProp(
parentError: ValidationError,
parentPath: string,
error: ValidationError,
): ValidationError {
const constraints = {};
for (const key in error.constraints) {
constraints[key] = `${parentError.property}.${error.constraints[key]}`;
constraints[key] = `${parentPath}.${error.constraints[key]}`;
}
return {
...error,

View File

@@ -71,7 +71,7 @@ export class ClassSerializerInterceptor implements NestInterceptor {
: plainOrClass;
}
private getContextOptions(
protected getContextOptions(
context: ExecutionContext,
): ClassTransformOptions | undefined {
return (

View File

@@ -1,7 +1,7 @@
import { Injectable } from '../decorators/core/injectable.decorator';
import { Optional } from '../decorators/core/optional.decorator';
import { clc, yellow } from '../utils/cli-colors.util';
import { isObject } from '../utils/shared.utils';
import { isObject, isPlainObject } from '../utils/shared.utils';
declare const process: any;
@@ -83,7 +83,7 @@ export class Logger implements LoggerService {
context = '',
isTimeDiffEnabled = true,
) {
this.printMessage(message, clc.red, context, isTimeDiffEnabled);
this.printMessage(message, clc.red, context, isTimeDiffEnabled, 'stderr');
this.printStackTrace(trace);
}
@@ -144,18 +144,22 @@ export class Logger implements LoggerService {
color: (message: string) => string,
context = '',
isTimeDiffEnabled?: boolean,
writeStreamType?: 'stdout' | 'stderr',
) {
const output = isObject(message)
const output = isPlainObject(message)
? `${color('Object:')}\n${JSON.stringify(message, null, 2)}\n`
: color(message);
const pidMessage = color(`[Nest] ${process.pid} - `);
const contextMessage = context ? yellow(`[${context}] `) : '';
const timestampDiff = this.updateAndGetTimestampDiff(isTimeDiffEnabled);
const instance = this.instance as typeof Logger;
process.stdout.write(
`${pidMessage}${instance.getTimestamp()} ${contextMessage}${output}${timestampDiff}\n`,
);
const instance = (this.instance as typeof Logger) ?? Logger;
const timestamp = instance.getTimestamp
? instance.getTimestamp()
: Logger.getTimestamp?.();
const computedMessage = `${pidMessage}${timestamp} ${contextMessage}${output}${timestampDiff}\n`;
process[writeStreamType ?? 'stdout'].write(computedMessage);
}
private static updateAndGetTimestampDiff(
@@ -173,6 +177,6 @@ export class Logger implements LoggerService {
if (!trace) {
return;
}
process.stdout.write(`${trace}\n`);
process.stderr.write(`${trace}\n`);
}
}

View File

@@ -4,6 +4,7 @@ import { Controller } from '../../decorators/core/controller.decorator';
describe('@Controller', () => {
const reflectedPath = 'test';
const reflectedHost = 'api.example.com';
const reflectedHostArray = ['api1.example.com', 'api2.example.com'];
@Controller(reflectedPath)
class Test {}
@@ -14,6 +15,9 @@ describe('@Controller', () => {
@Controller({ path: reflectedPath, host: reflectedHost })
class PathAndHostDecorator {}
@Controller({ path: reflectedPath, host: reflectedHostArray })
class PathAndHostArrayDecorator {}
@Controller({ host: reflectedHost })
class HostOnlyDecorator {}
@@ -29,6 +33,8 @@ describe('@Controller', () => {
expect(host).to.be.eql(reflectedHost);
const host2 = Reflect.getMetadata('host', HostOnlyDecorator);
expect(host2).to.be.eql(reflectedHost);
const host3 = Reflect.getMetadata('host', PathAndHostArrayDecorator);
expect(host3).to.be.eql(reflectedHostArray);
});
it('should set default path when no object passed as param', () => {

View File

@@ -1,7 +1,19 @@
import * as chai from 'chai';
import { expect } from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { Type } from 'class-transformer';
import {
IsBoolean,
IsDate,
IsDefined,
IsNumber,
IsString,
ValidateNested,
} from 'class-validator';
import { BadRequestException } from '../../exceptions';
import { ArgumentMetadata } from '../../interfaces/features/pipe-transform.interface';
import { ParseArrayPipe } from '../../pipes/parse-array.pipe';
chai.use(chaiAsPromised);
describe('ParseArrayPipe', () => {
let target: ParseArrayPipe;
@@ -102,6 +114,153 @@ describe('ParseArrayPipe', () => {
expect(item).to.be.instanceOf(ArrItem);
});
});
describe('when "stopAtFirstError" is explicitly turned off', () => {
it('should validate each item and concat errors', async () => {
class ArrItemWithProp {
@IsNumber()
number: number;
}
const pipe = new ParseArrayPipe({
items: ArrItemWithProp,
stopAtFirstError: false,
});
try {
await pipe.transform(
[
{ number: '1' },
{ number: '1' },
{ number: 1 },
] as ArrItemWithProp[],
{} as ArgumentMetadata,
);
} catch (err) {
expect(err).to.be.instanceOf(BadRequestException);
expect(err.getResponse().message).to.deep.equal([
'[0] number must be a number conforming to the specified constraints',
'[1] number must be a number conforming to the specified constraints',
]);
}
});
it('should validate each nested object and concat errors', async () => {
class RandomObject {
@IsDefined()
@IsBoolean()
isEnabled: boolean;
@IsString()
title: string;
@IsDate()
createdAt: Date;
constructor(partial: Partial<any>) {
Object.assign(this, partial);
}
}
class ArrItemObject {
@ValidateNested()
random: RandomObject;
}
const pipe = new ParseArrayPipe({
items: ArrItemObject,
stopAtFirstError: false,
});
try {
await pipe.transform(
[
{
random: new RandomObject({
isEnabled: true,
title: true,
createdAt: new Date(),
}),
},
{
random: new RandomObject({
title: 'ok',
createdAt: false,
}),
},
] as any[],
{} as ArgumentMetadata,
);
} catch (err) {
expect(err).to.be.instanceOf(BadRequestException);
expect(err.getResponse().message).to.deep.equal([
'[0] random.title must be a string',
'[1] random.isEnabled should not be null or undefined',
'[1] random.isEnabled must be a boolean value',
'[1] random.createdAt must be a Date instance',
]);
}
});
it('should validate each nested array and concat errors', async () => {
class RandomObject {
@IsDefined()
@IsBoolean()
isEnabled: boolean;
@IsString()
title: string;
@IsDate()
createdAt: Date;
constructor(partial: Partial<any>) {
Object.assign(this, partial);
}
}
class ArrItemObject {
@Type(() => RandomObject)
@ValidateNested({ each: true })
random: RandomObject[];
}
const pipe = new ParseArrayPipe({
items: ArrItemObject,
stopAtFirstError: false,
});
try {
await pipe.transform(
[
{
random: [
new RandomObject({
isEnabled: true,
title: true,
createdAt: new Date(),
}),
new RandomObject({
isEnabled: true,
title: true,
createdAt: new Date(),
}),
],
},
{
random: [
new RandomObject({
title: 'ok',
createdAt: false,
}),
],
},
] as any[],
{} as ArgumentMetadata,
);
} catch (err) {
expect(err).to.be.instanceOf(BadRequestException);
expect(err.getResponse().message).to.deep.equal([
'[0] random.0.title must be a string',
'[0] random.1.title must be a string',
'[1] random.0.isEnabled should not be null or undefined',
'[1] random.0.isEnabled must be a boolean value',
'[1] random.0.createdAt must be a Date instance',
]);
}
});
});
});
});
});

View File

@@ -8,6 +8,7 @@ import {
IsOptional,
IsString,
ValidateNested,
IsArray,
} from 'class-validator';
import { HttpStatus } from '../../enums';
import { UnprocessableEntityException } from '../../exceptions';
@@ -156,6 +157,32 @@ describe('ValidationPipe', () => {
]);
}
});
class TestModelForNestedArrayValidation {
@IsString()
public prop: string;
@IsArray()
@ValidateNested()
@Type(() => TestModel2)
public test: TestModel2[];
}
it('should provide complete path for nested errors', async () => {
try {
const model = new TestModelForNestedArrayValidation();
model.test = [new TestModel2()];
await target.transform(model, {
type: 'body',
metatype: TestModelForNestedArrayValidation,
});
} catch (err) {
expect(err.getResponse().message).to.be.eql([
'prop must be a string',
'test.0.prop1 must be a string',
'test.0.prop2 must be a boolean value',
]);
}
});
});
describe('when validation transforms', () => {
it('should return a TestModel instance', async () => {

View File

@@ -27,6 +27,12 @@ export const isPlainObject = (fn: any): fn is object => {
export const addLeadingSlash = (path?: string): string =>
path ? (path.charAt(0) !== '/' ? '/' + path : path) : '';
/**
* Deprecated. Use the "addLeadingSlash" function instead.
* @deprecated
*/
export const validatePath = addLeadingSlash;
export const isFunction = (fn: any): boolean => typeof fn === 'function';
export const isString = (fn: any): fn is string => typeof fn === 'string';
export const isConstructor = (fn: any): boolean => fn === 'constructor';

View File

@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
#### Principal Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
<td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
</tr></table>
#### Gold Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td></tr></table>
#### Silver Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
<td align="center" valign="middle">
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
</tr></table>
## Backers

View File

@@ -1,6 +1,9 @@
import { HttpServer, RequestMethod } from '@nestjs/common';
import { RequestHandler } from '@nestjs/common/interfaces';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from '@nestjs/common/interfaces/external/cors-options.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
/**
@@ -14,6 +17,14 @@ export abstract class AbstractHttpAdapter<
protected httpServer: TServer;
constructor(protected readonly instance: any) {}
all(path: string, handler: RequestHandler<TRequest, TResponse>);
all(handler: RequestHandler<TRequest, TResponse>);
all(path: any, handler?: any) {
throw new Error('Method not implemented.');
}
setBaseViewsDir?(path: string | string[]): this {
throw new Error('Method not implemented.');
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
public async init() {}
@@ -97,7 +108,10 @@ export abstract class AbstractHttpAdapter<
abstract setNotFoundHandler(handler: Function, prefix?: string);
abstract setHeader(response, name: string, value: string);
abstract registerParserMiddleware(prefix?: string);
abstract enableCors(options: CorsOptions, prefix?: string);
abstract enableCors(
options: CorsOptions | CorsOptionsDelegate<TRequest>,
prefix?: string,
);
abstract createMiddlewareFactory(
requestMethod: RequestMethod,
):

View File

@@ -14,12 +14,8 @@ export class ApplicationConfig {
private globalInterceptors: NestInterceptor[] = [];
private globalGuards: CanActivate[] = [];
private readonly globalRequestPipes: InstanceWrapper<PipeTransform>[] = [];
private readonly globalRequestFilters: InstanceWrapper<
ExceptionFilter
>[] = [];
private readonly globalRequestInterceptors: InstanceWrapper<
NestInterceptor
>[] = [];
private readonly globalRequestFilters: InstanceWrapper<ExceptionFilter>[] = [];
private readonly globalRequestInterceptors: InstanceWrapper<NestInterceptor>[] = [];
private readonly globalRequestGuards: InstanceWrapper<CanActivate>[] = [];
constructor(private ioAdapter: WebSocketAdapter | null = null) {}

View File

@@ -38,9 +38,7 @@ export interface ExternalContextOptions {
export class ExternalContextCreator {
private readonly contextUtils = new ContextUtils();
private readonly externalErrorProxy = new ExternalErrorProxy();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
ExternalHandlerMetadata
>();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<ExternalHandlerMetadata>();
private container: NestContainer;
constructor(

View File

@@ -13,18 +13,17 @@ export class ModuleCompiler {
public async compile(
metatype: Type<any> | DynamicModule | Promise<DynamicModule>,
): Promise<ModuleFactory> {
const { type, dynamicMetadata } = await this.extractMetadata(metatype);
const { type, dynamicMetadata } = this.extractMetadata(await metatype);
const token = this.moduleTokenFactory.create(type, dynamicMetadata);
return { type, dynamicMetadata, token };
}
public async extractMetadata(
metatype: Type<any> | DynamicModule | Promise<DynamicModule>,
): Promise<{
public extractMetadata(
metatype: Type<any> | DynamicModule,
): {
type: Type<any>;
dynamicMetadata?: Partial<DynamicModule> | undefined;
}> {
metatype = await metatype;
} {
if (!this.isDynamicModule(metatype)) {
return { type: metatype };
}

View File

@@ -69,82 +69,6 @@ export interface InjectorDependencyContext {
}
export class Injector {
public async loadMiddleware(
wrapper: InstanceWrapper,
collection: Map<string, InstanceWrapper>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const { metatype } = wrapper;
const targetWrapper = collection.get(metatype.name);
if (!isUndefined(targetWrapper.instance)) {
return;
}
const loadInstance = (instances: any[]) => {
targetWrapper.instance = targetWrapper.isDependencyTreeStatic()
? new (metatype as Type<any>)(...instances)
: Object.create(metatype.prototype);
};
await this.resolveConstructorParams(
wrapper,
moduleRef,
null,
loadInstance,
contextId,
inquirer,
);
}
public async loadController(
wrapper: InstanceWrapper<Controller>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
) {
const controllers = moduleRef.controllers;
await this.loadInstance<Controller>(
wrapper,
controllers,
moduleRef,
contextId,
wrapper,
);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
public async loadInjectable<T = any>(
wrapper: InstanceWrapper<T>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const injectables = moduleRef.injectables;
await this.loadInstance<T>(
wrapper,
injectables,
moduleRef,
contextId,
inquirer,
);
}
public async loadProvider(
wrapper: InstanceWrapper<Injectable>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const providers = moduleRef.providers;
await this.loadInstance<Injectable>(
wrapper,
providers,
moduleRef,
contextId,
inquirer,
);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
public loadPrototype<T>(
{ name }: InstanceWrapper<T>,
collection: Map<string, InstanceWrapper<T>>,
@@ -164,15 +88,6 @@ export class Injector {
}
}
public applyDoneHook<T>(wrapper: InstancePerContext<T>): () => void {
let done: () => void;
wrapper.donePromise = new Promise<void>((resolve, reject) => {
done = resolve;
});
wrapper.isPending = true;
return done;
}
public async loadInstance<T>(
wrapper: InstanceWrapper<T>,
collection: Map<string, InstanceWrapper>,
@@ -225,11 +140,91 @@ export class Injector {
);
}
public async loadMiddleware(
wrapper: InstanceWrapper,
collection: Map<string, InstanceWrapper>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const { metatype } = wrapper;
const targetWrapper = collection.get(metatype.name);
if (!isUndefined(targetWrapper.instance)) {
return;
}
targetWrapper.instance = Object.create(metatype.prototype);
await this.loadInstance(
wrapper,
collection,
moduleRef,
contextId,
inquirer || wrapper,
);
}
public async loadController(
wrapper: InstanceWrapper<Controller>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
) {
const controllers = moduleRef.controllers;
await this.loadInstance<Controller>(
wrapper,
controllers,
moduleRef,
contextId,
wrapper,
);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
public async loadInjectable<T = any>(
wrapper: InstanceWrapper<T>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const injectables = moduleRef.injectables;
await this.loadInstance<T>(
wrapper,
injectables,
moduleRef,
contextId,
inquirer,
);
}
public async loadProvider(
wrapper: InstanceWrapper<Injectable>,
moduleRef: Module,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
) {
const providers = moduleRef.providers;
await this.loadInstance<Injectable>(
wrapper,
providers,
moduleRef,
contextId,
inquirer,
);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
public applyDoneHook<T>(wrapper: InstancePerContext<T>): () => void {
let done: () => void;
wrapper.donePromise = new Promise<void>((resolve, reject) => {
done = resolve;
});
wrapper.isPending = true;
return done;
}
public async resolveConstructorParams<T>(
wrapper: InstanceWrapper<T>,
moduleRef: Module,
inject: InjectorDependency[],
callback: (args: unknown[]) => void,
callback: (args: unknown[]) => void | Promise<void>,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
parentInquirer?: InstanceWrapper,
@@ -274,7 +269,7 @@ export class Injector {
if (!instanceHost.isResolved && !paramWrapper.forwardRef) {
isResolved = false;
}
return instanceHost && instanceHost.instance;
return instanceHost?.instance;
} catch (err) {
const isOptional = optionalDependenciesIds.includes(index);
if (!isOptional) {
@@ -372,7 +367,7 @@ export class Injector {
public async resolveComponentHost<T>(
moduleRef: Module,
instanceWrapper: InstanceWrapper<T>,
instanceWrapper: InstanceWrapper<T | Promise<T>>,
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
): Promise<InstanceWrapper> {

View File

@@ -47,11 +47,15 @@ export class ModuleTokenFactory {
private replacer(key: string, value: any) {
if (typeof value === 'function') {
const isClass = /^class\s/.test(Function.prototype.toString.call(value));
const funcAsString = value.toString();
const isClass = /^class\s/.test(funcAsString);
if (isClass) {
return value.name;
}
return hash(value.toString(), { ignoreUnknown: true });
return hash(funcAsString, { ignoreUnknown: true });
}
if (typeof value === 'symbol') {
return value.toString();
}
return value;
}

View File

@@ -168,6 +168,9 @@ export class MiddlewareModule {
if (isUndefined(instanceWrapper)) {
throw new RuntimeException();
}
if (instanceWrapper.isTransient) {
return;
}
await this.bindHandler(
instanceWrapper,
applicationRef,

View File

@@ -5,7 +5,7 @@ import {
LogLevel,
ShutdownSignal,
} from '@nestjs/common';
import { Abstract, Scope } from '@nestjs/common/interfaces';
import { Abstract, DynamicModule, Scope } from '@nestjs/common/interfaces';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { isEmpty } from '@nestjs/common/utils/shared.utils';
import { iterate } from 'iterare';
@@ -22,6 +22,7 @@ import {
callModuleInitHook,
} from './hooks';
import { ContextId } from './injector';
import { ModuleCompiler } from './injector/compiler';
import { NestContainer } from './injector/container';
import { Injector } from './injector/injector';
import { InstanceLinksHost } from './injector/instance-links-host';
@@ -33,8 +34,10 @@ import { Module } from './injector/module';
export class NestApplicationContext implements INestApplicationContext {
protected isInitialized = false;
protected readonly injector = new Injector();
private shutdownCleanupRef?: (...args: unknown[]) => unknown;
private readonly activeShutdownSignals = new Array<string>();
private readonly moduleCompiler = new ModuleCompiler();
private shutdownCleanupRef?: (...args: unknown[]) => unknown;
private _instanceLinksHost: InstanceLinksHost;
private get instanceLinksHost() {
@@ -55,14 +58,20 @@ export class NestApplicationContext implements INestApplicationContext {
this.contextModule = modules.next().value;
}
public select<T>(moduleType: Type<T>): INestApplicationContext {
const modules = this.container.getModules();
const moduleMetatype = this.contextModule.metatype;
const scope = this.scope.concat(moduleMetatype);
const moduleTokenFactory = this.container.getModuleTokenFactory();
public select<T>(
moduleType: Type<T> | DynamicModule,
): INestApplicationContext {
const modulesContainer = this.container.getModules();
const contextModuleCtor = this.contextModule.metatype;
const scope = this.scope.concat(contextModuleCtor);
const token = moduleTokenFactory.create(moduleType);
const selectedModule = modules.get(token);
const moduleTokenFactory = this.container.getModuleTokenFactory();
const { type, dynamicMetadata } = this.moduleCompiler.extractMetadata(
moduleType,
);
const token = moduleTokenFactory.create(type, dynamicMetadata);
const selectedModule = modulesContainer.get(token);
if (!selectedModule) {
throw new UnknownModuleException();
}

View File

@@ -9,7 +9,10 @@ import {
PipeTransform,
WebSocketAdapter,
} from '@nestjs/common';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from '@nestjs/common/interfaces/external/cors-options.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
import { Logger } from '@nestjs/common/services/logger.service';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
@@ -102,11 +105,15 @@ export class NestApplication
if (!this.appOptions || !this.appOptions.cors) {
return undefined;
}
const isCorsOptionsObj = isObject(this.appOptions.cors);
if (!isCorsOptionsObj) {
const passCustomOptions =
isObject(this.appOptions.cors) ||
typeof this.appOptions.cors === 'function';
if (!passCustomOptions) {
return this.enableCors();
}
return this.enableCors(this.appOptions.cors as CorsOptions);
return this.enableCors(
this.appOptions.cors as CorsOptions | CorsOptionsDelegate<any>,
);
}
public createServer<T = any>(): T {
@@ -224,7 +231,7 @@ export class NestApplication
return this;
}
public enableCors(options?: CorsOptions): void {
public enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void {
this.httpAdapter.enableCors(options);
}
@@ -348,7 +355,7 @@ export class NestApplication
}
private listenToPromise(microservice: INestMicroservice) {
return new Promise(async resolve => {
return new Promise<void>(async resolve => {
await microservice.listen(resolve);
});
}

View File

@@ -215,10 +215,10 @@ export class NestFactoryStatic {
}
private applyLogger(options: NestApplicationContextOptions | undefined) {
if (!options) {
if (!options || options?.logger === true || isNil(options?.logger)) {
return;
}
!isNil(options.logger) && Logger.overrideLogger(options.logger);
Logger.overrideLogger(options.logger);
}
private createHttpAdapter<T = any>(httpServer?: T): AbstractHttpAdapter {

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/core",
"version": "7.5.5",
"version": "7.6.10",
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
"author": "Kamil Mysliwiec",
"license": "MIT",
@@ -30,17 +30,31 @@
"@nuxtjs/opencollective": "0.3.2",
"fast-safe-stringify": "2.0.7",
"iterare": "1.2.1",
"object-hash": "2.0.3",
"object-hash": "2.1.1",
"path-to-regexp": "3.2.0",
"tslib": "2.0.3",
"uuid": "8.3.1"
"tslib": "2.1.0",
"uuid": "8.3.2"
},
"devDependencies": {
"@nestjs/common": "7.5.5"
"@nestjs/common": "7.6.10"
},
"peerDependencies": {
"@nestjs/common": "^7.0.0",
"@nestjs/microservices": "^7.0.0",
"@nestjs/platform-express": "^7.0.0",
"@nestjs/websockets": "^7.0.0",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0"
},
"peerDependenciesMeta": {
"@nestjs/websockets": {
"optional": true
},
"@nestjs/microservices": {
"optional": true
},
"@nestjs/platform-express": {
"optional": true
}
}
}

View File

@@ -73,7 +73,7 @@ export class RouterExplorer {
module: string,
applicationRef: T,
basePath: string,
host: string,
host: string | string[],
) {
const { instance } = instanceWrapper;
const routerPaths = this.scanForPaths(instance);
@@ -150,7 +150,7 @@ export class RouterExplorer {
instanceWrapper: InstanceWrapper,
moduleKey: string,
basePath: string,
host: string,
host: string | string[],
) {
(routePaths || []).forEach(pathProperties => {
const { path, requestMethod } = pathProperties;
@@ -179,7 +179,7 @@ export class RouterExplorer {
instanceWrapper: InstanceWrapper,
moduleKey: string,
basePath: string,
host: string,
host: string | string[],
) {
const {
path: paths,
@@ -216,14 +216,24 @@ export class RouterExplorer {
});
}
private applyHostFilter(host: string, handler: Function) {
private applyHostFilter(host: string | string[], handler: Function) {
if (!host) {
return handler;
}
const httpAdapterRef = this.container.getHttpAdapterRef();
const keys = [];
const re = pathToRegexp(host, keys);
const hosts = Array.isArray(host) ? host : [host];
const hostRegExps = hosts.map((host: string) => {
const keys = [];
const regexp = pathToRegexp(host, keys);
return { regexp, keys };
});
const unsupportedFilteringErrorMessage = Array.isArray(host)
? `HTTP adapter does not support filtering on hosts: ["${host.join(
'", "',
)}"]`
: `HTTP adapter does not support filtering on host: "${host}"`;
return <TRequest extends Record<string, any> = any, TResponse = any>(
req: TRequest,
@@ -232,14 +242,17 @@ export class RouterExplorer {
) => {
(req as Record<string, any>).hosts = {};
const hostname = httpAdapterRef.getRequestHostname(req) || '';
const match = hostname.match(re);
if (match) {
keys.forEach((key, i) => (req.hosts[key.name] = match[i + 1]));
return handler(req, res, next);
for (const exp of hostRegExps) {
const match = hostname.match(exp.regexp);
if (match) {
exp.keys.forEach((key, i) => (req.hosts[key.name] = match[i + 1]));
return handler(req, res, next);
}
}
if (!next) {
throw new InternalServerErrorException(
`HTTP adapter does not support filtering on host: "${host}"`,
unsupportedFilteringErrorMessage,
);
}
return next();

View File

@@ -132,7 +132,7 @@ export class RoutesResolver implements Resolver {
private getHostMetadata(
metatype: Type<unknown> | Function,
): string | undefined {
): string | string[] | undefined {
return Reflect.getMetadata(HOST_METADATA, metatype);
}
}

View File

@@ -189,28 +189,28 @@ describe('Injector', () => {
});
describe('loadMiddleware', () => {
let resolveConstructorParams: sinon.SinonSpy;
let loadInstanceSpy: sinon.SinonSpy;
beforeEach(() => {
resolveConstructorParams = sinon.spy();
injector.resolveConstructorParams = resolveConstructorParams;
loadInstanceSpy = sinon.spy();
injector.loadInstance = loadInstanceSpy;
});
it('should call "resolveConstructorParams" when instance is not resolved', () => {
it('should call "loadInstance" when instance is not resolved', () => {
const collection = {
get: (...args) => ({}),
set: (...args) => {},
};
injector.loadMiddleware(
{ metatype: { name: '' } } as any,
{ metatype: { name: '', prototype: {} } } as any,
collection as any,
null,
);
expect(resolveConstructorParams.called).to.be.true;
expect(loadInstanceSpy.called).to.be.true;
});
it('should not call "resolveConstructorParams" when instance is not resolved', () => {
it('should not call "loadInstanceSpy" when instance is not resolved', () => {
const collection = {
get: (...args) => ({
instance: {},
@@ -223,7 +223,7 @@ describe('Injector', () => {
collection as any,
null,
);
expect(resolveConstructorParams.called).to.be.false;
expect(loadInstanceSpy.called).to.be.false;
});
});

View File

@@ -30,6 +30,7 @@ describe('ModuleTokenFactory', () => {
const token = factory.create(type, {
providers: [{}],
} as any);
expect(token).to.be.deep.eq(
hash({
id: moduleId,
@@ -62,6 +63,24 @@ describe('ModuleTokenFactory', () => {
'{"providers":["Provider"],"exports":["Provider"]}',
);
});
it('should serialize symbols in a dynamic metadata object', () => {
const metadata = {
providers: [
{
provide: Symbol('a'),
useValue: 'a',
},
{
provide: Symbol('b'),
useValue: 'b',
},
],
};
expect(factory.getDynamicMetadataToken(metadata)).to.be.eql(
'{"providers":[{"provide":"Symbol(a)","useValue":"a"},{"provide":"Symbol(b)","useValue":"b"}]}',
);
});
});
describe('when metadata does not exist', () => {
it('should return empty string', () => {

View File

@@ -125,7 +125,7 @@ data: hello
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control':
'private, no-cache, no-store, must-revalidate, max-age=0',
'private, no-cache, no-store, must-revalidate, max-age=0, no-transform',
'Transfer-Encoding': 'identity',
Pragma: 'no-cache',
Expire: '0',

View File

@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
#### Principal Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></td>
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
<td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
</tr></table>
#### Gold Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td></tr></table>
#### Silver Sponsors
<table style="text-align:center;"><tr><td>
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
<td align="center" valign="middle">
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
</tr></table>
## Backers

View File

@@ -8,7 +8,6 @@ import {
} from '../constants';
import { KafkaResponseDeserializer } from '../deserializers/kafka-response.deserializer';
import { KafkaHeaders } from '../enums';
import { InvalidKafkaClientTopicPartitionException } from '../errors/invalid-kafka-client-topic-partition.exception';
import { InvalidKafkaClientTopicException } from '../errors/invalid-kafka-client-topic.exception';
import {
BrokersFunction,
@@ -24,7 +23,7 @@ import {
import {
KafkaLogger,
KafkaParser,
KafkaRoundRobinPartitionAssigner,
KafkaReplyPartitionAssigner,
} from '../helpers';
import {
KafkaOptions,
@@ -46,7 +45,7 @@ export class ClientKafka extends ClientProxy {
protected producer: Producer = null;
protected logger = new Logger(ClientKafka.name);
protected responsePatterns: string[] = [];
protected consumerAssignments: { [key: string]: number[] } = {};
protected consumerAssignments: { [key: string]: number } = {};
protected brokers: string[] | BrokersFunction;
protected clientId: string;
@@ -59,17 +58,16 @@ export class ClientKafka extends ClientProxy {
this.getOptionsProp(this.options, 'client') || ({} as KafkaConfig);
const consumerOptions =
this.getOptionsProp(this.options, 'consumer') || ({} as ConsumerConfig);
const postfixId =
this.getOptionsProp(this.options, 'postfixId') || '-client';
this.brokers = clientOptions.brokers || [KAFKA_DEFAULT_BROKER];
// Append a unique id to the clientId and groupId
// so they don't collide with a microservices client
this.clientId =
(clientOptions.clientId || KAFKA_DEFAULT_CLIENT) +
(clientOptions.clientIdPostfix || '-client');
this.groupId =
(consumerOptions.groupId || KAFKA_DEFAULT_GROUP) +
(clientOptions.clientIdPostfix || '-client');
(clientOptions.clientId || KAFKA_DEFAULT_CLIENT) + postfixId;
this.groupId = (consumerOptions.groupId || KAFKA_DEFAULT_GROUP) + postfixId;
kafkaPackage = loadPackage('kafkajs', ClientKafka.name, () =>
require('kafkajs'),
@@ -99,11 +97,8 @@ export class ClientKafka extends ClientProxy {
this.client = this.createClient();
const partitionAssigners = [
(
config: ConstructorParameters<
typeof KafkaRoundRobinPartitionAssigner
>[0],
) => new KafkaRoundRobinPartitionAssigner(config),
(config: ConstructorParameters<typeof KafkaReplyPartitionAssigner>[1]) =>
new KafkaReplyPartitionAssigner(this, config),
] as any[];
const consumerOptions = Object.assign(
@@ -188,6 +183,10 @@ export class ClientKafka extends ClientProxy {
};
}
public getConsumerAssignments() {
return this.consumerAssignments;
}
protected dispatchEvent(packet: OutgoingEvent): Promise<any> {
const pattern = this.normalizePattern(packet.pattern);
const outgoingEvent = this.serializer.serialize(packet.data);
@@ -202,17 +201,13 @@ export class ClientKafka extends ClientProxy {
}
protected getReplyTopicPartition(topic: string): string {
const topicAssignments = this.consumerAssignments[topic];
if (isUndefined(topicAssignments)) {
const minimumPartition = this.consumerAssignments[topic];
if (isUndefined(minimumPartition)) {
throw new InvalidKafkaClientTopicException(topic);
}
// if the current member isn't listening to
// any partitions on the topic then throw an error.
if (isUndefined(topicAssignments[0])) {
throw new InvalidKafkaClientTopicPartitionException(topic);
}
return topicAssignments[0].toString();
// get the minimum partition
return minimumPartition.toString();
}
protected publish(
@@ -241,7 +236,7 @@ export class ClientKafka extends ClientProxy {
},
this.options.send || {},
);
this.producer.send(message);
this.producer.send(message).catch(err => callback({ err }));
return () => this.routingMap.delete(packet.id);
} catch (err) {
@@ -254,7 +249,18 @@ export class ClientKafka extends ClientProxy {
}
protected setConsumerAssignments(data: ConsumerGroupJoinEvent): void {
this.consumerAssignments = data.payload.memberAssignment;
const consumerAssignments: { [key: string]: number } = {};
// only need to set the minimum
Object.keys(data.payload.memberAssignment).forEach(memberId => {
const minimumPartition = Math.min(
...data.payload.memberAssignment[memberId],
);
consumerAssignments[memberId] = minimumPartition;
});
this.consumerAssignments = consumerAssignments;
}
protected initializeSerializer(options: KafkaOptions['options']) {

View File

@@ -157,7 +157,7 @@ export class ClientMqtt extends ClientProxy {
const pattern = this.normalizePattern(packet.pattern);
const serializedPacket = this.serializer.serialize(packet);
return new Promise((resolve, reject) =>
return new Promise<void>((resolve, reject) =>
this.mqttClient.publish(pattern, JSON.stringify(serializedPacket), err =>
err ? reject(err) : resolve(),
),

View File

@@ -111,7 +111,7 @@ export class ClientNats extends ClientProxy {
const pattern = this.normalizePattern(packet.pattern);
const serializedPacket = this.serializer.serialize(packet);
return new Promise((resolve, reject) =>
return new Promise<void>((resolve, reject) =>
this.natsClient.publish(pattern, serializedPacket as any, err =>
err ? reject(err) : resolve(),
),

View File

@@ -1,6 +1,7 @@
import { Transport } from '../enums/transport.enum';
import {
ClientOptions,
CustomClientOptions,
TcpClientOptions,
} from '../interfaces/client-metadata.interface';
import { Closeable } from '../interfaces/closeable.interface';
@@ -30,7 +31,16 @@ export class ClientProxyFactory {
clientOptions: { transport: Transport.GRPC } & ClientOptions,
): ClientGrpcProxy;
public static create(clientOptions: ClientOptions): ClientProxy & Closeable;
public static create(clientOptions: ClientOptions): ClientProxy & Closeable {
public static create(
clientOptions: CustomClientOptions,
): ClientProxy & Closeable;
public static create(
clientOptions: ClientOptions | CustomClientOptions,
): ClientProxy & Closeable {
if (this.isCustomClientOptions(clientOptions)) {
const { customClass, options } = clientOptions;
return new customClass(options);
}
const { transport, options } = clientOptions;
switch (transport) {
case Transport.REDIS:
@@ -49,4 +59,10 @@ export class ClientProxyFactory {
return new ClientTCP(options as TcpClientOptions['options']);
}
}
private static isCustomClientOptions(
options: ClientOptions | CustomClientOptions,
): options is CustomClientOptions {
return !!(options as CustomClientOptions).customClass;
}
}

View File

@@ -84,17 +84,25 @@ export abstract class ClientProxy {
): (packet: WritePacket) => void {
return ({ err, response, isDisposed }: WritePacket) => {
if (err) {
return observer.error(err);
return observer.error(this.serializeError(err));
} else if (response !== undefined && isDisposed) {
observer.next(response);
observer.next(this.serializeResponse(response));
return observer.complete();
} else if (isDisposed) {
return observer.complete();
}
observer.next(response);
observer.next(this.serializeResponse(response));
};
}
protected serializeError(err: any): any {
return err;
}
protected serializeResponse(response: any): any {
return response;
}
protected assignPacketId(packet: ReadPacket): ReadPacket & PacketId {
const id = randomStringGenerator();
return Object.assign(packet, { id });

View File

@@ -190,7 +190,7 @@ export class ClientRedis extends ClientProxy {
const pattern = this.normalizePattern(packet.pattern);
const serializedPacket = this.serializer.serialize(packet);
return new Promise((resolve, reject) =>
return new Promise<void>((resolve, reject) =>
this.pubClient.publish(pattern, JSON.stringify(serializedPacket), err =>
err ? reject(err) : resolve(),
),

View File

@@ -16,9 +16,9 @@ import {
RQM_DEFAULT_QUEUE_OPTIONS,
RQM_DEFAULT_URL,
} from '../constants';
import { RmqUrl } from '../external/rmq-url.interface';
import { ReadPacket, RmqOptions, WritePacket } from '../interfaces';
import { ClientProxy } from './client-proxy';
import { RmqUrl } from '../external/rmq-url.interface';
let rqmPackage: any = {};
@@ -204,14 +204,14 @@ export class ClientRMQ extends ClientProxy {
protected dispatchEvent(packet: ReadPacket): Promise<any> {
const serializedPacket = this.serializer.serialize(packet);
return new Promise((resolve, reject) =>
return new Promise<void>((resolve, reject) =>
this.channel.sendToQueue(
this.queue,
Buffer.from(JSON.stringify(serializedPacket)),
{
persistent: this.persistent,
},
err => (err ? reject(err) : resolve()),
(err: unknown) => (err ? reject(err) : resolve()),
),
);
}

View File

@@ -41,9 +41,7 @@ export interface RpcHandlerMetadata {
export class RpcContextCreator {
private readonly contextUtils = new ContextUtils();
private readonly rpcParamsFactory = new RpcParamsFactory();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
RpcHandlerMetadata
>();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<RpcHandlerMetadata>();
constructor(
private readonly rpcProxy: RpcProxy,

View File

@@ -1,9 +0,0 @@
import { RuntimeException } from '@nestjs/core/errors/exceptions/runtime.exception';
export class InvalidKafkaClientTopicPartitionException extends RuntimeException {
constructor(topic?: string) {
super(
`The client consumer subscribed to the topic (${topic}) which is not assigned to any partitions.`,
);
}
}

View File

@@ -1,931 +0,0 @@
/// <reference types="node" />
import * as net from 'net';
import * as tls from 'tls';
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = T | U extends object
? (Without<T, U> & U) | (Without<U, T> & T)
: T | U;
export declare class Kafka {
constructor(config: KafkaConfig);
producer(config?: ProducerConfig): Producer;
consumer(config?: ConsumerConfig): Consumer;
admin(config?: AdminConfig): Admin;
logger(): Logger;
}
export type BrokersFunction = () => string[] | Promise<string[]>;
export interface KafkaConfig {
brokers: string[] | BrokersFunction;
ssl?: tls.ConnectionOptions | boolean;
sasl?: SASLOptions;
clientId?: string;
clientIdPostfix?: string;
connectionTimeout?: number;
authenticationTimeout?: number;
reauthenticationThreshold?: number;
requestTimeout?: number;
enforceRequestTimeout?: boolean;
retry?: RetryOptions;
socketFactory?: ISocketFactory;
logLevel?: logLevel;
logCreator?: logCreator;
}
export type ISocketFactory = (
host: string,
port: number,
ssl: tls.ConnectionOptions,
onConnect: () => void,
) => net.Socket;
export type SASLMechanism = 'plain' | 'scram-sha-256' | 'scram-sha-512' | 'aws';
export interface SASLOptions {
mechanism: SASLMechanism;
username: string;
password: string;
}
export interface ProducerConfig {
createPartitioner?: ICustomPartitioner;
retry?: RetryOptions;
metadataMaxAge?: number;
allowAutoTopicCreation?: boolean;
idempotent?: boolean;
transactionalId?: string;
transactionTimeout?: number;
maxInFlightRequests?: number;
}
export interface Message {
key?: Buffer | string | null;
value: Buffer | string | null;
partition?: number;
headers?: IHeaders;
timestamp?: string;
}
export interface PartitionerArgs {
topic: string;
partitionMetadata: PartitionMetadata[];
message: Message;
}
export type ICustomPartitioner = () => (args: PartitionerArgs) => number;
export type DefaultPartitioner = ICustomPartitioner;
export type JavaCompatiblePartitioner = ICustomPartitioner;
export let Partitioners: {
DefaultPartitioner: DefaultPartitioner;
JavaCompatiblePartitioner: JavaCompatiblePartitioner;
};
export type PartitionMetadata = {
partitionErrorCode: number;
partitionId: number;
leader: number;
replicas: number[];
isr: number[];
offlineReplicas?: number[];
};
export interface IHeaders {
[key: string]: Buffer | string;
}
export interface ConsumerConfig {
groupId: string;
partitionAssigners?: PartitionAssigner[];
metadataMaxAge?: number;
sessionTimeout?: number;
rebalanceTimeout?: number;
heartbeatInterval?: number;
maxBytesPerPartition?: number;
minBytes?: number;
maxBytes?: number;
maxWaitTimeInMs?: number;
retry?: RetryOptions & {
restartOnFailure?: (err: Error) => Promise<boolean>;
};
allowAutoTopicCreation?: boolean;
maxInFlightRequests?: number;
readUncommitted?: boolean;
rackId?: string;
}
export type PartitionAssigner = (config: { cluster: Cluster }) => Assigner;
export interface CoordinatorMetadata {
errorCode: number;
coordinator: {
nodeId: number;
host: string;
port: number;
};
}
export type Cluster = {
isConnected(): boolean;
connect(): Promise<void>;
disconnect(): Promise<void>;
refreshMetadata(): Promise<void>;
refreshMetadataIfNecessary(): Promise<void>;
addTargetTopic(topic: string): Promise<void>;
findBroker(node: { nodeId: string }): Promise<Broker>;
findControllerBroker(): Promise<Broker>;
findTopicPartitionMetadata(topic: string): PartitionMetadata[];
findLeaderForPartitions(
topic: string,
partitions: number[],
): { [leader: string]: number[] };
findGroupCoordinator(group: { groupId: string }): Promise<Broker>;
findGroupCoordinatorMetadata(group: {
groupId: string;
}): Promise<CoordinatorMetadata>;
defaultOffset(config: { fromBeginning: boolean }): number;
fetchTopicsOffset(
topics: Array<
{
topic: string;
partitions: Array<{ partition: number }>;
} & XOR<{ fromBeginning: boolean }, { fromTimestamp: number }>
>,
): Promise<{
topic: string;
partitions: Array<{ partition: number; offset: string }>;
}>;
};
export type Assignment = { [topic: string]: number[] };
export type GroupMember = { memberId: string; memberMetadata: Buffer };
export type GroupMemberAssignment = {
memberId: string;
memberAssignment: Buffer;
};
export type GroupState = { name: string; metadata: Buffer };
export type Assigner = {
name: string;
version: number;
assign(group: {
members: GroupMember[];
topics: string[];
}): Promise<GroupMemberAssignment[]>;
protocol(subscription: { topics: string[] }): GroupState;
};
export interface RetryOptions {
maxRetryTime?: number;
initialRetryTime?: number;
factor?: number;
multiplier?: number;
retries?: number;
}
export interface AdminConfig {
retry?: RetryOptions;
}
export interface ITopicConfig {
topic: string;
numPartitions?: number;
replicationFactor?: number;
replicaAssignment?: object[];
configEntries?: object[];
}
export interface ITopicPartitionConfig {
topic: string;
count: number;
assignments?: Array<Array<number>>;
}
export interface ITopicMetadata {
name: string;
partitions: PartitionMetadata[];
}
export enum ResourceTypes {
UNKNOWN = 0,
ANY = 1,
TOPIC = 2,
GROUP = 3,
CLUSTER = 4,
TRANSACTIONAL_ID = 5,
DELEGATION_TOKEN = 6,
}
export interface ResourceConfigQuery {
type: ResourceTypes;
name: string;
configNames?: string[];
}
export interface ConfigEntries {
configName: string;
configValue: string;
isDefault: boolean;
isSensitive: boolean;
readOnly: boolean;
configSynonyms: ConfigSynonyms[];
}
export interface ConfigSynonyms {
configName: string;
configValue: string;
configSource: number;
}
export interface DescribeConfigResponse {
resources: {
configEntries: ConfigEntries[];
errorCode: number;
errorMessage: string;
resourceName: string;
resourceType: ResourceTypes;
}[];
throttleTime: number;
}
export interface IResourceConfig {
type: ResourceTypes;
name: string;
configEntries: { name: string; value: string }[];
}
type ValueOf<T> = T[keyof T];
export type AdminEvents = {
CONNECT: 'admin.connect';
DISCONNECT: 'admin.disconnect';
REQUEST: 'admin.network.request';
REQUEST_TIMEOUT: 'admin.network.request_timeout';
REQUEST_QUEUE_SIZE: 'admin.network.request_queue_size';
};
export interface InstrumentationEvent<T> {
id: string;
type: string;
timestamp: number;
payload: T;
}
export type RemoveInstrumentationEventListener<T> = () => void;
export type ConnectEvent = InstrumentationEvent<null>;
export type DisconnectEvent = InstrumentationEvent<null>;
export type RequestEvent = InstrumentationEvent<{
apiKey: number;
apiName: string;
apiVersion: number;
broker: string;
clientId: string;
correlationId: number;
createdAt: number;
duration: number;
pendingDuration: number;
sentAt: number;
size: number;
}>;
export type RequestTimeoutEvent = InstrumentationEvent<{
apiKey: number;
apiName: string;
apiVersion: number;
broker: string;
clientId: string;
correlationId: number;
createdAt: number;
pendingDuration: number;
sentAt: number;
}>;
export type RequestQueueSizeEvent = InstrumentationEvent<{
broker: string;
clientId: string;
queueSize: number;
}>;
export interface SeekEntry {
partition: number;
offset: string;
}
export type Admin = {
connect(): Promise<void>;
disconnect(): Promise<void>;
listTopics(): Promise<string[]>;
createTopics(options: {
validateOnly?: boolean;
waitForLeaders?: boolean;
timeout?: number;
topics: ITopicConfig[];
}): Promise<boolean>;
deleteTopics(options: { topics: string[]; timeout?: number }): Promise<void>;
createPartitions(options: {
validateOnly?: boolean;
timeout?: number;
topicPartitions: ITopicPartitionConfig[];
}): Promise<boolean>;
fetchTopicMetadata(options?: {
topics: string[];
}): Promise<{ topics: Array<ITopicMetadata> }>;
fetchOffsets(options: {
groupId: string;
topic: string;
}): Promise<Array<SeekEntry & { metadata: string | null }>>;
fetchTopicOffsets(
topic: string,
): Promise<Array<SeekEntry & { high: string; low: string }>>;
fetchTopicOffsetsByTimestamp(
topic: string,
timestamp?: number,
): Promise<Array<SeekEntry>>;
describeCluster(): Promise<{
brokers: Array<{ nodeId: number; host: string; port: number }>;
controller: number | null;
clusterId: string;
}>;
setOffsets(options: {
groupId: string;
topic: string;
partitions: SeekEntry[];
}): Promise<void>;
resetOffsets(options: {
groupId: string;
topic: string;
earliest: boolean;
}): Promise<void>;
describeConfigs(configs: {
resources: ResourceConfigQuery[];
includeSynonyms: boolean;
}): Promise<DescribeConfigResponse>;
alterConfigs(configs: {
validateOnly: boolean;
resources: IResourceConfig[];
}): Promise<any>;
listGroups(): Promise<{ groups: GroupOverview[] }>;
deleteGroups(groupIds: string[]): Promise<DeleteGroupsResult[]>;
describeGroups(groupIds: string[]): Promise<GroupDescriptions>;
logger(): Logger;
on(
eventName: ValueOf<AdminEvents>,
listener: (...args: any[]) => void,
): RemoveInstrumentationEventListener<typeof eventName>;
events: AdminEvents;
};
export let PartitionAssigners: { roundRobin: PartitionAssigner };
export interface ISerializer<T> {
encode(value: T): Buffer;
decode(buffer: Buffer): T | null;
}
export type MemberMetadata = {
version: number;
topics: string[];
userData: Buffer;
};
export type MemberAssignment = {
version: number;
assignment: Assignment;
userData: Buffer;
};
export let AssignerProtocol: {
MemberMetadata: ISerializer<MemberMetadata>;
MemberAssignment: ISerializer<MemberAssignment>;
};
export enum logLevel {
NOTHING = 0,
ERROR = 1,
WARN = 2,
INFO = 4,
DEBUG = 5,
}
export interface LogEntry {
namespace: string;
level: logLevel;
label: string;
log: LoggerEntryContent;
}
export interface LoggerEntryContent {
readonly timestamp: Date;
readonly message: string;
[key: string]: any;
}
export type logCreator = (logLevel: logLevel) => (entry: LogEntry) => void;
export type Logger = {
info: (message: string, extra?: object) => void;
error: (message: string, extra?: object) => void;
warn: (message: string, extra?: object) => void;
debug: (message: string, extra?: object) => void;
};
export type Broker = {
isConnected(): boolean;
connect(): Promise<void>;
disconnect(): Promise<void>;
apiVersions(): Promise<{
[apiKey: number]: { minVersion: number; maxVersion: number };
}>;
metadata(
topics: string[],
): Promise<{
brokers: Array<{
nodeId: number;
host: string;
port: number;
rack?: string;
}>;
topicMetadata: Array<{
topicErrorCode: number;
topic: number;
partitionMetadata: PartitionMetadata[];
}>;
}>;
offsetCommit(request: {
groupId: string;
groupGenerationId: number;
memberId: string;
retentionTime?: number;
topics: Array<{
topic: string;
partitions: Array<{ partition: number; offset: string }>;
}>;
}): Promise<any>;
fetch(request: {
replicaId?: number;
isolationLevel?: number;
maxWaitTime?: number;
minBytes?: number;
maxBytes?: number;
topics: Array<{
topic: string;
partitions: Array<{
partition: number;
fetchOffset: string;
maxBytes: number;
}>;
}>;
rackId?: string;
}): Promise<any>;
};
export type KafkaMessage = {
key: Buffer;
value: Buffer | null;
timestamp: string;
size: number;
attributes: number;
offset: string;
headers?: IHeaders;
};
export interface ProducerRecord {
topic: string;
messages: Message[];
acks?: number;
timeout?: number;
compression?: CompressionTypes;
}
export type RecordMetadata = {
topicName: string;
partition: number;
errorCode: number;
offset: string;
timestamp: string;
};
export interface TopicMessages {
topic: string;
messages: Message[];
}
export interface ProducerBatch {
acks?: number;
timeout?: number;
compression?: CompressionTypes;
topicMessages?: TopicMessages[];
}
export interface PartitionOffset {
partition: number;
offset: string;
}
export interface TopicOffsets {
topic: string;
partitions: PartitionOffset[];
}
export interface Offsets {
topics: TopicOffsets[];
}
type Sender = {
send(record: ProducerRecord): Promise<RecordMetadata[]>;
sendBatch(batch: ProducerBatch): Promise<RecordMetadata[]>;
};
export type ProducerEvents = {
CONNECT: 'producer.connect';
DISCONNECT: 'producer.disconnect';
REQUEST: 'producer.network.request';
REQUEST_TIMEOUT: 'producer.network.request_timeout';
REQUEST_QUEUE_SIZE: 'producer.network.request_queue_size';
};
export type Producer = Sender & {
connect(): Promise<void>;
disconnect(): Promise<void>;
isIdempotent(): boolean;
events: ProducerEvents;
on(
eventName: ValueOf<ProducerEvents>,
listener: (...args: any[]) => void,
): RemoveInstrumentationEventListener<typeof eventName>;
transaction(): Promise<Transaction>;
logger(): Logger;
};
export type Transaction = Sender & {
sendOffsets(offsets: Offsets & { consumerGroupId: string }): Promise<void>;
commit(): Promise<void>;
abort(): Promise<void>;
isActive(): boolean;
};
export type ConsumerGroup = {
groupId: string;
generationId: number;
memberId: string;
coordinator: Broker;
};
export type MemberDescription = {
clientHost: string;
clientId: string;
memberId: string;
memberAssignment: Buffer;
memberMetadata: Buffer;
};
export type GroupDescription = {
groupId: string;
members: MemberDescription[];
protocol: string;
protocolType: string;
state: string;
};
export type GroupDescriptions = {
groups: GroupDescription[];
};
export type TopicPartitions = { topic: string; partitions: number[] };
export type TopicPartitionOffsetAndMetadata = {
topic: string;
partition: number;
offset: string;
metadata?: string | null;
};
// TODO: Remove with 2.x
export type TopicPartitionOffsetAndMedata = TopicPartitionOffsetAndMetadata;
export type Batch = {
topic: string;
partition: number;
highWatermark: string;
messages: KafkaMessage[];
isEmpty(): boolean;
firstOffset(): string | null;
lastOffset(): string;
offsetLag(): string;
offsetLagLow(): string;
};
export type GroupOverview = {
groupId: string;
protocolType: string;
};
export type DeleteGroupsResult = {
groupId: string;
errorCode?: number;
};
export type ConsumerEvents = {
HEARTBEAT: 'consumer.heartbeat';
COMMIT_OFFSETS: 'consumer.commit_offsets';
GROUP_JOIN: 'consumer.group_join';
FETCH_START: 'consumer.fetch_start';
FETCH: 'consumer.fetch';
START_BATCH_PROCESS: 'consumer.start_batch_process';
END_BATCH_PROCESS: 'consumer.end_batch_process';
CONNECT: 'consumer.connect';
DISCONNECT: 'consumer.disconnect';
STOP: 'consumer.stop';
CRASH: 'consumer.crash';
REQUEST: 'consumer.network.request';
REQUEST_TIMEOUT: 'consumer.network.request_timeout';
REQUEST_QUEUE_SIZE: 'consumer.network.request_queue_size';
};
export type ConsumerHeartbeatEvent = InstrumentationEvent<{
groupId: string;
memberId: string;
groupGenerationId: number;
}>;
export type ConsumerCommitOffsetsEvent = InstrumentationEvent<{
groupId: string;
memberId: string;
groupGenerationId: number;
topics: {
topic: string;
partitions: {
offset: string;
partition: string;
}[];
}[];
}>;
export interface IMemberAssignment {
[key: string]: number[];
}
export type ConsumerGroupJoinEvent = InstrumentationEvent<{
duration: number;
groupId: string;
isLeader: boolean;
leaderId: string;
groupProtocol: string;
memberId: string;
memberAssignment: IMemberAssignment;
}>;
export type ConsumerFetchEvent = InstrumentationEvent<{
numberOfBatches: number;
duration: number;
}>;
interface IBatchProcessEvent {
topic: string;
partition: number;
highWatermark: string;
offsetLag: string;
offsetLagLow: string;
batchSize: number;
firstOffset: string;
lastOffset: string;
}
export type ConsumerStartBatchProcessEvent = InstrumentationEvent<
IBatchProcessEvent
>;
export type ConsumerEndBatchProcessEvent = InstrumentationEvent<
IBatchProcessEvent & { duration: number }
>;
export type ConsumerCrashEvent = InstrumentationEvent<{
error: Error;
groupId: string;
}>;
export interface OffsetsByTopicPartition {
topics: TopicOffsets[];
}
export interface EachMessagePayload {
topic: string;
partition: number;
message: KafkaMessage;
}
export interface EachBatchPayload {
batch: Batch;
resolveOffset(offset: string): void;
heartbeat(): Promise<void>;
commitOffsetsIfNecessary(offsets?: Offsets): Promise<void>;
uncommittedOffsets(): OffsetsByTopicPartition;
isRunning(): boolean;
isStale(): boolean;
}
/**
* Type alias to keep compatibility with @types/kafkajs
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/712ad9d59ccca6a3cc92f347fea0d1c7b02f5eeb/types/kafkajs/index.d.ts#L321-L325
*/
export type ConsumerEachMessagePayload = EachMessagePayload;
/**
* Type alias to keep compatibility with @types/kafkajs
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/712ad9d59ccca6a3cc92f347fea0d1c7b02f5eeb/types/kafkajs/index.d.ts#L327-L336
*/
export type ConsumerEachBatchPayload = EachBatchPayload;
export type ConsumerRunConfig = {
autoCommit?: boolean;
autoCommitInterval?: number | null;
autoCommitThreshold?: number | null;
eachBatchAutoResolve?: boolean;
partitionsConsumedConcurrently?: number;
eachBatch?: (payload: EachBatchPayload) => Promise<void>;
eachMessage?: (payload: EachMessagePayload) => Promise<void>;
};
export type ConsumerSubscribeTopic = {
topic: string | RegExp;
fromBeginning?: boolean;
};
export type Consumer = {
connect(): Promise<void>;
disconnect(): Promise<void>;
subscribe(topic: ConsumerSubscribeTopic): Promise<void>;
stop(): Promise<void>;
run(config?: ConsumerRunConfig): Promise<void>;
commitOffsets(
topicPartitions: Array<TopicPartitionOffsetAndMetadata>,
): Promise<void>;
seek(topicPartition: {
topic: string;
partition: number;
offset: string;
}): void;
describeGroup(): Promise<GroupDescription>;
pause(topics: Array<{ topic: string; partitions?: number[] }>): void;
paused(): TopicPartitions[];
resume(topics: Array<{ topic: string; partitions?: number[] }>): void;
on(
eventName: ValueOf<ConsumerEvents>,
listener: (...args: any[]) => void,
): RemoveInstrumentationEventListener<typeof eventName>;
logger(): Logger;
events: ConsumerEvents;
};
export enum CompressionTypes {
None = 0,
GZIP = 1,
Snappy = 2,
LZ4 = 3,
ZSTD = 4,
}
export let CompressionCodecs: {
[CompressionTypes.GZIP]: () => any;
[CompressionTypes.Snappy]: () => any;
[CompressionTypes.LZ4]: () => any;
[CompressionTypes.ZSTD]: () => any;
};
export declare class KafkaJSError extends Error {
constructor(e: Error | string, metadata?: KafkaJSErrorMetadata);
}
export declare class KafkaJSNonRetriableError extends KafkaJSError {
constructor(e: Error | string);
}
export declare class KafkaJSProtocolError extends KafkaJSError {
constructor(e: Error | string);
}
export declare class KafkaJSOffsetOutOfRange extends KafkaJSProtocolError {
constructor(e: Error | string, metadata?: KafkaJSOffsetOutOfRangeMetadata);
}
export declare class KafkaJSNumberOfRetriesExceeded extends KafkaJSNonRetriableError {
constructor(
e: Error | string,
metadata?: KafkaJSNumberOfRetriesExceededMetadata,
);
}
export declare class KafkaJSConnectionError extends KafkaJSError {
constructor(e: Error | string, metadata?: KafkaJSConnectionErrorMetadata);
}
export declare class KafkaJSRequestTimeoutError extends KafkaJSError {
constructor(e: Error | string, metadata?: KafkaJSRequestTimeoutErrorMetadata);
}
export declare class KafkaJSMetadataNotLoaded extends KafkaJSError {
constructor();
}
export declare class KafkaJSTopicMetadataNotLoaded extends KafkaJSMetadataNotLoaded {
constructor(
e: Error | string,
metadata?: KafkaJSTopicMetadataNotLoadedMetadata,
);
}
export declare class KafkaJSStaleTopicMetadataAssignment extends KafkaJSError {
constructor(
e: Error | string,
metadata?: KafkaJSStaleTopicMetadataAssignmentMetadata,
);
}
export declare class KafkaJSServerDoesNotSupportApiKey extends KafkaJSNonRetriableError {
constructor(
e: Error | string,
metadata?: KafkaJSServerDoesNotSupportApiKeyMetadata,
);
}
export declare class KafkaJSBrokerNotFound extends KafkaJSError {
constructor();
}
export declare class KafkaJSPartialMessageError extends KafkaJSError {
constructor();
}
export declare class KafkaJSSASLAuthenticationError extends KafkaJSError {
constructor();
}
export declare class KafkaJSGroupCoordinatorNotFound extends KafkaJSError {
constructor();
}
export declare class KafkaJSNotImplemented extends KafkaJSError {
constructor();
}
export declare class KafkaJSTimeout extends KafkaJSError {
constructor();
}
export declare class KafkaJSLockTimeout extends KafkaJSError {
constructor();
}
export declare class KafkaJSUnsupportedMagicByteInMessageSet extends KafkaJSError {
constructor();
}
export declare class KafkaJSDeleteGroupsError extends KafkaJSError {
constructor(e: Error | string, groups?: KafkaJSDeleteGroupsErrorGroups[]);
}
export interface KafkaJSDeleteGroupsErrorGroups {
groupId: string;
errorCode: number;
error: KafkaJSError;
}
export interface KafkaJSErrorMetadata {
retriable?: boolean;
topic?: string;
partitionId?: number;
metadata?: PartitionMetadata;
}
export interface KafkaJSOffsetOutOfRangeMetadata {
topic: string;
partition: number;
}
export interface KafkaJSNumberOfRetriesExceededMetadata {
retryCount: number;
retryTime: number;
}
export interface KafkaJSConnectionErrorMetadata {
broker?: string;
code?: string;
}
export interface KafkaJSRequestTimeoutErrorMetadata {
broker: string;
clientId: string;
correlationId: number;
createdAt: number;
sentAt: number;
pendingDuration: number;
}
export interface KafkaJSTopicMetadataNotLoadedMetadata {
topic: string;
}
export interface KafkaJSStaleTopicMetadataAssignmentMetadata {
topic: string;
unknownPartitions: PartitionMetadata[];
}
export interface KafkaJSServerDoesNotSupportApiKeyMetadata {
apiKey: number;
apiName: string;
}

View File

@@ -1,9 +1,19 @@
/**
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/kafkajs/index.d.ts
* Do NOT add NestJS logic to this interface. It is meant to ONLY represent the types for the kafkajs package.
*
* @see https://github.com/tulios/kafkajs/blob/master/types/index.d.ts
*/
/// <reference types="node" />
import * as net from 'net';
import * as tls from 'tls';
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = T | U extends object
? (Without<T, U> & U) | (Without<U, T> & T)
: T | U;
export declare class Kafka {
constructor(config: KafkaConfig);
producer(config?: ProducerConfig): Producer;
@@ -19,7 +29,6 @@ export interface KafkaConfig {
ssl?: tls.ConnectionOptions | boolean;
sasl?: SASLOptions;
clientId?: string;
clientIdPostfix?: string;
connectionTimeout?: number;
authenticationTimeout?: number;
reauthenticationThreshold?: number;
@@ -31,19 +40,40 @@ export interface KafkaConfig {
logCreator?: logCreator;
}
export type ISocketFactory = (
host: string,
port: number,
ssl: tls.ConnectionOptions,
onConnect: () => void,
) => net.Socket;
export interface SASLOptions {
mechanism: 'plain' | 'scram-sha-256' | 'scram-sha-512' | 'aws';
username: string;
password: string;
export interface ISocketFactoryArgs {
host: string;
port: number;
ssl: tls.ConnectionOptions;
onConnect: () => void;
}
export type ISocketFactory = (args: ISocketFactoryArgs) => net.Socket;
export interface OauthbearerProviderResponse {
value: string;
}
type SASLMechanismOptionsMap = {
plain: { username: string; password: string };
'scram-sha-256': { username: string; password: string };
'scram-sha-512': { username: string; password: string };
aws: {
authorizationIdentity: string;
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
};
oauthbearer: {
oauthBearerProvider: () => Promise<OauthbearerProviderResponse>;
};
};
export type SASLMechanism = keyof SASLMechanismOptionsMap;
type SASLMechanismOptions<T> = T extends SASLMechanism
? { mechanism: T } & SASLMechanismOptionsMap[T]
: never;
export type SASLOptions = SASLMechanismOptions<SASLMechanism>;
export interface ProducerConfig {
createPartitioner?: ICustomPartitioner;
retry?: RetryOptions;
@@ -70,24 +100,25 @@ export interface PartitionerArgs {
}
export type ICustomPartitioner = () => (args: PartitionerArgs) => number;
export type DefaultPartitioner = (args: PartitionerArgs) => number;
export type JavaCompatiblePartitioner = (args: PartitionerArgs) => number;
export type DefaultPartitioner = ICustomPartitioner;
export type JavaCompatiblePartitioner = ICustomPartitioner;
export let Partitioners: {
DefaultPartitioner: DefaultPartitioner;
JavaCompatiblePartitioner: JavaCompatiblePartitioner;
};
export interface PartitionMetadata {
export type PartitionMetadata = {
partitionErrorCode: number;
partitionId: number;
leader: number;
replicas: number[];
isr: number[];
}
offlineReplicas?: number[];
};
export interface IHeaders {
[key: string]: Buffer;
[key: string]: Buffer | string | undefined;
}
export interface ConsumerConfig {
@@ -101,15 +132,16 @@ export interface ConsumerConfig {
minBytes?: number;
maxBytes?: number;
maxWaitTimeInMs?: number;
retry?: RetryOptions;
retry?: RetryOptions & {
restartOnFailure?: (err: Error) => Promise<boolean>;
};
allowAutoTopicCreation?: boolean;
maxInFlightRequests?: number;
readUncommitted?: boolean;
rackId?: string;
}
export interface PartitionAssigner {
new (config: { cluster: Cluster }): Assigner;
}
export type PartitionAssigner = (config: { cluster: Cluster }) => Assigner;
export interface CoordinatorMetadata {
errorCode: number;
@@ -120,7 +152,7 @@ export interface CoordinatorMetadata {
};
}
export interface Cluster {
export type Cluster = {
isConnected(): boolean;
connect(): Promise<void>;
disconnect(): Promise<void>;
@@ -140,46 +172,38 @@ export interface Cluster {
}): Promise<CoordinatorMetadata>;
defaultOffset(config: { fromBeginning: boolean }): number;
fetchTopicsOffset(
topics: Array<{
topic: string;
partitions: Array<{ partition: number }>;
fromBeginning: boolean;
}>,
topics: Array<
{
topic: string;
partitions: Array<{ partition: number }>;
} & XOR<{ fromBeginning: boolean }, { fromTimestamp: number }>
>,
): Promise<{
topic: string;
partitions: Array<{ partition: number; offset: string }>;
}>;
}
};
export interface Assignment {
[topic: string]: number[];
}
export type Assignment = { [topic: string]: number[] };
export interface GroupMember {
memberId: string;
memberMetadata: MemberMetadata;
}
export type GroupMember = { memberId: string; memberMetadata: Buffer };
export interface GroupMemberAssignment {
export type GroupMemberAssignment = {
memberId: string;
memberAssignment: Buffer;
}
};
export interface GroupState {
name: string;
metadata: Buffer;
}
export type GroupState = { name: string; metadata: Buffer };
export interface Assigner {
export type Assigner = {
name: string;
version: number;
assign(group: {
members: GroupMember[];
topics: string[];
userData: Buffer;
}): Promise<GroupMemberAssignment[]>;
protocol(subscription: { topics: string[]; userData: Buffer }): GroupState;
}
protocol(subscription: { topics: string[] }): GroupState;
};
export interface RetryOptions {
maxRetryTime?: number;
@@ -201,12 +225,22 @@ export interface ITopicConfig {
configEntries?: object[];
}
export interface ITopicPartitionConfig {
topic: string;
count: number;
assignments?: Array<Array<number>>;
}
export interface ITopicMetadata {
name: string;
partitions: PartitionMetadata[];
}
export enum ResourceType {
/**
* @deprecated
* Use ConfigResourceTypes or AclResourceTypes
*/
export enum ResourceTypes {
UNKNOWN = 0,
ANY = 1,
TOPIC = 2,
@@ -216,10 +250,58 @@ export enum ResourceType {
DELEGATION_TOKEN = 6,
}
export enum AclResourceTypes {
UNKNOWN = 0,
ANY = 1,
TOPIC = 2,
GROUP = 3,
CLUSTER = 4,
TRANSACTIONAL_ID = 5,
DELEGATION_TOKEN = 6,
}
export enum ConfigResourceTypes {
UNKNOWN = 0,
TOPIC = 2,
BROKER = 4,
BROKER_LOGGER = 8,
}
export enum AclPermissionTypes {
UNKNOWN = 0,
ANY = 1,
DENY = 2,
ALLOW = 3,
}
export enum AclOperationTypes {
UNKNOWN = 0,
ANY = 1,
ALL = 2,
READ = 3,
WRITE = 4,
CREATE = 5,
DELETE = 6,
ALTER = 7,
DESCRIBE = 8,
CLUSTER_ACTION = 9,
DESCRIBE_CONFIGS = 10,
ALTER_CONFIGS = 11,
IDEMPOTENT_WRITE = 12,
}
export enum ResourcePatternTypes {
UNKNOWN = 0,
ANY = 1,
MATCH = 2,
LITERAL = 3,
PREFIXED = 4,
}
export interface ResourceConfigQuery {
type: ResourceType;
type: ResourceTypes | ConfigResourceTypes;
name: string;
configNames: string[];
configNames?: string[];
}
export interface ConfigEntries {
@@ -243,26 +325,26 @@ export interface DescribeConfigResponse {
errorCode: number;
errorMessage: string;
resourceName: string;
resourceType: ResourceType;
resourceType: ResourceTypes | ConfigResourceTypes;
}[];
throttleTime: number;
}
export interface IResourceConfig {
type: ResourceType;
type: ResourceTypes | ConfigResourceTypes;
name: string;
configEntries: { name: string; value: string }[];
}
type ValueOf<T> = T[keyof T];
export interface AdminEvents {
export type AdminEvents = {
CONNECT: 'admin.connect';
DISCONNECT: 'admin.disconnect';
REQUEST: 'admin.network.request';
REQUEST_TIMEOUT: 'admin.network.request_timeout';
REQUEST_QUEUE_SIZE: 'admin.network.request_queue_size';
}
};
export interface InstrumentationEvent<T> {
id: string;
@@ -271,6 +353,8 @@ export interface InstrumentationEvent<T> {
payload: T;
}
export type RemoveInstrumentationEventListener<T> = () => void;
export type ConnectEvent = InstrumentationEvent<null>;
export type DisconnectEvent = InstrumentationEvent<null>;
export type RequestEvent = InstrumentationEvent<{
@@ -308,9 +392,69 @@ export interface SeekEntry {
offset: string;
}
export interface Admin {
export interface Acl {
principal: string;
host: string;
operation: AclOperationTypes;
permissionType: AclPermissionTypes;
}
export interface AclResource {
resourceType: AclResourceTypes;
resourceName: string;
resourcePatternType: ResourcePatternTypes;
}
export type AclEntry = Acl & AclResource;
export type DescribeAclResource = AclResource & {
acl: Acl[];
};
export interface DescribeAclResponse {
throttleTime: number;
errorCode: number;
errorMessage?: string;
resources: DescribeAclResource[];
}
export interface AclFilter {
resourceType: AclResourceTypes;
resourceName?: string;
resourcePatternType: ResourcePatternTypes;
principal?: string;
host?: string;
operation: AclOperationTypes;
permissionType: AclPermissionTypes;
}
export interface MatchingAcl {
errorCode: number;
errorMessage?: string;
resourceType: AclResourceTypes;
resourceName: string;
resourcePatternType: ResourcePatternTypes;
principal: string;
host: string;
operation: AclOperationTypes;
permissionType: AclPermissionTypes;
}
export interface DeleteAclFilterResponses {
errorCode: number;
errorMessage?: string;
matchingAcls: MatchingAcl[];
}
export interface DeleteAclResponse {
throttleTime: number;
filterResponses: DeleteAclFilterResponses[];
}
export type Admin = {
connect(): Promise<void>;
disconnect(): Promise<void>;
listTopics(): Promise<string[]>;
createTopics(options: {
validateOnly?: boolean;
waitForLeaders?: boolean;
@@ -318,20 +462,31 @@ export interface Admin {
topics: ITopicConfig[];
}): Promise<boolean>;
deleteTopics(options: { topics: string[]; timeout?: number }): Promise<void>;
fetchTopicMetadata(options: {
createPartitions(options: {
validateOnly?: boolean;
timeout?: number;
topicPartitions: ITopicPartitionConfig[];
}): Promise<boolean>;
fetchTopicMetadata(options?: {
topics: string[];
}): Promise<{ topics: Array<ITopicMetadata> }>;
fetchOffsets(options: {
groupId: string;
topic: string;
}): Promise<
Array<{ partition: number; offset: string; metadata: string | null }>
>;
resolveOffsets?: boolean;
}): Promise<Array<SeekEntry & { metadata: string | null }>>;
fetchTopicOffsets(
topic: string,
): Promise<
Array<{ partition: number; offset: string; high: string; low: string }>
>;
): Promise<Array<SeekEntry & { high: string; low: string }>>;
fetchTopicOffsetsByTimestamp(
topic: string,
timestamp?: number,
): Promise<Array<SeekEntry>>;
describeCluster(): Promise<{
brokers: Array<{ nodeId: number; host: string; port: number }>;
controller: number | null;
clusterId: string;
}>;
setOffsets(options: {
groupId: string;
topic: string;
@@ -350,29 +505,42 @@ export interface Admin {
validateOnly: boolean;
resources: IResourceConfig[];
}): Promise<any>;
listGroups(): Promise<{ groups: GroupOverview[] }>;
deleteGroups(groupIds: string[]): Promise<DeleteGroupsResult[]>;
describeGroups(groupIds: string[]): Promise<GroupDescriptions>;
describeAcls(options: AclFilter): Promise<DescribeAclResponse>;
deleteAcls(options: { filters: AclFilter[] }): Promise<DeleteAclResponse>;
createAcls(options: { acl: AclEntry[] }): Promise<boolean>;
deleteTopicRecords(options: {
topic: string;
partitions: SeekEntry[];
}): Promise<void>;
logger(): Logger;
on(eventName: ValueOf<AdminEvents>, listener: (...args: any[]) => void): void;
on(
eventName: ValueOf<AdminEvents>,
listener: (...args: any[]) => void,
): RemoveInstrumentationEventListener<typeof eventName>;
events: AdminEvents;
}
};
export let PartitionAssigners: { roundRobin: PartitionAssigner };
export interface ISerializer<T> {
encode(value: T): Buffer;
decode(buffer: Buffer): T;
decode(buffer: Buffer): T | null;
}
export interface MemberMetadata {
export type MemberMetadata = {
version: number;
topics: string[];
userData: Buffer;
}
};
export interface MemberAssignment {
export type MemberAssignment = {
version: number;
assignment: Assignment;
userData: Buffer;
}
};
export let AssignerProtocol: {
MemberMetadata: ISerializer<MemberMetadata>;
@@ -400,11 +568,16 @@ export interface LoggerEntryContent {
[key: string]: any;
}
export type Logger = (entry: LogEntry) => void;
export type logCreator = (logLevel: logLevel) => (entry: LogEntry) => void;
export type logCreator = (logLevel: string) => (entry: LogEntry) => void;
export type Logger = {
info: (message: string, extra?: object) => void;
error: (message: string, extra?: object) => void;
warn: (message: string, extra?: object) => void;
debug: (message: string, extra?: object) => void;
};
export interface Broker {
export type Broker = {
isConnected(): boolean;
connect(): Promise<void>;
disconnect(): Promise<void>;
@@ -414,7 +587,12 @@ export interface Broker {
metadata(
topics: string[],
): Promise<{
brokers: Array<{ nodeId: number; host: string; port: number }>;
brokers: Array<{
nodeId: number;
host: string;
port: number;
rack?: string;
}>;
topicMetadata: Array<{
topicErrorCode: number;
topic: number;
@@ -431,17 +609,33 @@ export interface Broker {
partitions: Array<{ partition: number; offset: string }>;
}>;
}): Promise<any>;
}
fetch(request: {
replicaId?: number;
isolationLevel?: number;
maxWaitTime?: number;
minBytes?: number;
maxBytes?: number;
topics: Array<{
topic: string;
partitions: Array<{
partition: number;
fetchOffset: string;
maxBytes: number;
}>;
}>;
rackId?: string;
}): Promise<any>;
};
export interface KafkaMessage {
export type KafkaMessage = {
key: Buffer;
value: Buffer;
value: Buffer | null;
timestamp: string;
size: number;
attributes: number;
offset: string;
headers?: IHeaders;
}
};
export interface ProducerRecord {
topic: string;
@@ -451,13 +645,16 @@ export interface ProducerRecord {
compression?: CompressionTypes;
}
export interface RecordMetadata {
export type RecordMetadata = {
topicName: string;
partition: number;
errorCode: number;
offset: string;
timestamp: string;
}
offset?: string;
timestamp?: string;
baseOffset?: string;
logAppendTime?: string;
logStartOffset?: string;
};
export interface TopicMessages {
topic: string;
@@ -465,10 +662,10 @@ export interface TopicMessages {
}
export interface ProducerBatch {
acks: number;
timeout: number;
compression: CompressionTypes;
topicMessages: TopicMessages[];
acks?: number;
timeout?: number;
compression?: CompressionTypes;
topicMessages?: TopicMessages[];
}
export interface PartitionOffset {
@@ -485,18 +682,18 @@ export interface Offsets {
topics: TopicOffsets[];
}
interface Sender {
type Sender = {
send(record: ProducerRecord): Promise<RecordMetadata[]>;
sendBatch(batch: ProducerBatch): Promise<RecordMetadata[]>;
}
};
export interface ProducerEvents {
export type ProducerEvents = {
CONNECT: 'producer.connect';
DISCONNECT: 'producer.disconnect';
REQUEST: 'producer.network.request';
REQUEST_TIMEOUT: 'producer.network.request_timeout';
REQUEST_QUEUE_SIZE: 'producer.network.request_queue_size';
}
};
export type Producer = Sender & {
connect(): Promise<void>;
@@ -506,7 +703,7 @@ export type Producer = Sender & {
on(
eventName: ValueOf<ProducerEvents>,
listener: (...args: any[]) => void,
): void;
): RemoveInstrumentationEventListener<typeof eventName>;
transaction(): Promise<Transaction>;
logger(): Logger;
};
@@ -518,41 +715,54 @@ export type Transaction = Sender & {
isActive(): boolean;
};
export interface ConsumerGroup {
export type ConsumerGroup = {
groupId: string;
generationId: number;
memberId: string;
coordinator: Broker;
}
};
export interface MemberDescription {
export type MemberDescription = {
clientHost: string;
clientId: string;
memberId: string;
memberAssignment: Buffer;
memberMetadata: Buffer;
}
};
export interface GroupDescription {
// See https://github.com/apache/kafka/blob/2.4.0/clients/src/main/java/org/apache/kafka/common/ConsumerGroupState.java#L25
export type ConsumerGroupState =
| 'Unknown'
| 'PreparingRebalance'
| 'CompletingRebalance'
| 'Stable'
| 'Dead'
| 'Empty';
export type GroupDescription = {
groupId: string;
members: MemberDescription[];
protocol: string;
protocolType: string;
state: string;
}
state: ConsumerGroupState;
};
export interface TopicPartitions {
topic: string;
partitions: number[];
}
export interface TopicPartitionOffsetAndMedata {
export type GroupDescriptions = {
groups: GroupDescription[];
};
export type TopicPartitions = { topic: string; partitions: number[] };
export type TopicPartitionOffsetAndMetadata = {
topic: string;
partition: number;
offset: string;
metadata?: string | null;
}
};
export interface Batch {
// TODO: Remove with 2.x
export type TopicPartitionOffsetAndMedata = TopicPartitionOffsetAndMetadata;
export type Batch = {
topic: string;
partition: number;
highWatermark: string;
@@ -562,12 +772,24 @@ export interface Batch {
lastOffset(): string;
offsetLag(): string;
offsetLagLow(): string;
}
};
export interface ConsumerEvents {
export type GroupOverview = {
groupId: string;
protocolType: string;
};
export type DeleteGroupsResult = {
groupId: string;
errorCode?: number;
error?: KafkaJSProtocolError;
};
export type ConsumerEvents = {
HEARTBEAT: 'consumer.heartbeat';
COMMIT_OFFSETS: 'consumer.commit_offsets';
GROUP_JOIN: 'consumer.group_join';
FETCH_START: 'consumer.fetch_start';
FETCH: 'consumer.fetch';
START_BATCH_PROCESS: 'consumer.start_batch_process';
END_BATCH_PROCESS: 'consumer.end_batch_process';
@@ -575,10 +797,11 @@ export interface ConsumerEvents {
DISCONNECT: 'consumer.disconnect';
STOP: 'consumer.stop';
CRASH: 'consumer.crash';
RECEIVED_UNSUBSCRIBED_TOPICS: 'consumer.received_unsubscribed_topics';
REQUEST: 'consumer.network.request';
REQUEST_TIMEOUT: 'consumer.network.request_timeout';
REQUEST_QUEUE_SIZE: 'consumer.network.request_queue_size';
}
};
export type ConsumerHeartbeatEvent = InstrumentationEvent<{
groupId: string;
memberId: string;
@@ -622,15 +845,22 @@ interface IBatchProcessEvent {
firstOffset: string;
lastOffset: string;
}
export type ConsumerStartBatchProcessEvent = InstrumentationEvent<
IBatchProcessEvent
>;
export type ConsumerStartBatchProcessEvent = InstrumentationEvent<IBatchProcessEvent>;
export type ConsumerEndBatchProcessEvent = InstrumentationEvent<
IBatchProcessEvent & { duration: number }
>;
export type ConsumerCrashEvent = InstrumentationEvent<{
error: Error;
groupId: string;
restart: boolean;
}>;
export type ConsumerReceivedUnsubcribedTopicsEvent = InstrumentationEvent<{
groupId: string;
generationId: number;
memberId: string;
assignedTopics: string[];
topicsSubscribed: string[];
topicsNotSubscribed: string[];
}>;
export interface OffsetsByTopicPartition {
@@ -648,7 +878,7 @@ export interface EachBatchPayload {
resolveOffset(offset: string): void;
heartbeat(): Promise<void>;
commitOffsetsIfNecessary(offsets?: Offsets): Promise<void>;
uncommittedOffsets(): Promise<OffsetsByTopicPartition>;
uncommittedOffsets(): OffsetsByTopicPartition;
isRunning(): boolean;
isStale(): boolean;
}
@@ -665,25 +895,29 @@ export type ConsumerEachMessagePayload = EachMessagePayload;
*/
export type ConsumerEachBatchPayload = EachBatchPayload;
export interface Consumer {
export type ConsumerRunConfig = {
autoCommit?: boolean;
autoCommitInterval?: number | null;
autoCommitThreshold?: number | null;
eachBatchAutoResolve?: boolean;
partitionsConsumedConcurrently?: number;
eachBatch?: (payload: EachBatchPayload) => Promise<void>;
eachMessage?: (payload: EachMessagePayload) => Promise<void>;
};
export type ConsumerSubscribeTopic = {
topic: string | RegExp;
fromBeginning?: boolean;
};
export type Consumer = {
connect(): Promise<void>;
disconnect(): Promise<void>;
subscribe(topic: {
topic: string | RegExp;
fromBeginning?: boolean;
}): Promise<void>;
subscribe(topic: ConsumerSubscribeTopic): Promise<void>;
stop(): Promise<void>;
run(config?: {
autoCommit?: boolean;
autoCommitInterval?: number | null;
autoCommitThreshold?: number | null;
eachBatchAutoResolve?: boolean;
partitionsConsumedConcurrently?: number;
eachBatch?: (payload: EachBatchPayload) => Promise<void>;
eachMessage?: (payload: EachMessagePayload) => Promise<void>;
}): Promise<void>;
run(config?: ConsumerRunConfig): Promise<void>;
commitOffsets(
topicPartitions: Array<TopicPartitionOffsetAndMedata>,
topicPartitions: Array<TopicPartitionOffsetAndMetadata>,
): Promise<void>;
seek(topicPartition: {
topic: string;
@@ -692,14 +926,15 @@ export interface Consumer {
}): void;
describeGroup(): Promise<GroupDescription>;
pause(topics: Array<{ topic: string; partitions?: number[] }>): void;
paused(): TopicPartitions[];
resume(topics: Array<{ topic: string; partitions?: number[] }>): void;
on(
eventName: ValueOf<ConsumerEvents>,
listener: (...args: any[]) => void,
): void;
): RemoveInstrumentationEventListener<typeof eventName>;
logger(): Logger;
events: ConsumerEvents;
}
};
export enum CompressionTypes {
None = 0,
@@ -715,3 +950,186 @@ export let CompressionCodecs: {
[CompressionTypes.LZ4]: () => any;
[CompressionTypes.ZSTD]: () => any;
};
export declare class KafkaJSError extends Error {
readonly message: Error['message'];
readonly name: string;
readonly retriable: boolean;
readonly helpUrl?: string;
constructor(e: Error | string, metadata?: KafkaJSErrorMetadata);
}
export declare class KafkaJSNonRetriableError extends KafkaJSError {
constructor(e: Error | string);
}
export declare class KafkaJSProtocolError extends KafkaJSError {
readonly code: number;
readonly type: string;
constructor(e: Error | string);
}
export declare class KafkaJSOffsetOutOfRange extends KafkaJSProtocolError {
readonly topic: string;
readonly partition: number;
constructor(e: Error | string, metadata?: KafkaJSOffsetOutOfRangeMetadata);
}
export declare class KafkaJSNumberOfRetriesExceeded extends KafkaJSNonRetriableError {
readonly stack: string;
readonly originalError: Error;
readonly retryCount: number;
readonly retryTime: number;
constructor(
e: Error | string,
metadata?: KafkaJSNumberOfRetriesExceededMetadata,
);
}
export declare class KafkaJSConnectionError extends KafkaJSError {
readonly broker: string;
constructor(e: Error | string, metadata?: KafkaJSConnectionErrorMetadata);
}
export declare class KafkaJSRequestTimeoutError extends KafkaJSError {
readonly broker: string;
readonly correlationId: number;
readonly createdAt: number;
readonly sentAt: number;
readonly pendingDuration: number;
constructor(e: Error | string, metadata?: KafkaJSRequestTimeoutErrorMetadata);
}
export declare class KafkaJSMetadataNotLoaded extends KafkaJSError {
constructor();
}
export declare class KafkaJSTopicMetadataNotLoaded extends KafkaJSMetadataNotLoaded {
readonly topic: string;
constructor(
e: Error | string,
metadata?: KafkaJSTopicMetadataNotLoadedMetadata,
);
}
export declare class KafkaJSStaleTopicMetadataAssignment extends KafkaJSError {
readonly topic: string;
readonly unknownPartitions: number;
constructor(
e: Error | string,
metadata?: KafkaJSStaleTopicMetadataAssignmentMetadata,
);
}
export declare class KafkaJSServerDoesNotSupportApiKey extends KafkaJSNonRetriableError {
readonly apiKey: number;
readonly apiName: string;
constructor(
e: Error | string,
metadata?: KafkaJSServerDoesNotSupportApiKeyMetadata,
);
}
export declare class KafkaJSBrokerNotFound extends KafkaJSError {
constructor();
}
export declare class KafkaJSPartialMessageError extends KafkaJSError {
constructor();
}
export declare class KafkaJSSASLAuthenticationError extends KafkaJSError {
constructor();
}
export declare class KafkaJSGroupCoordinatorNotFound extends KafkaJSError {
constructor();
}
export declare class KafkaJSNotImplemented extends KafkaJSError {
constructor();
}
export declare class KafkaJSTimeout extends KafkaJSError {
constructor();
}
export declare class KafkaJSLockTimeout extends KafkaJSError {
constructor();
}
export declare class KafkaJSUnsupportedMagicByteInMessageSet extends KafkaJSError {
constructor();
}
export declare class KafkaJSDeleteGroupsError extends KafkaJSError {
readonly groups: DeleteGroupsResult[];
constructor(e: Error | string, groups?: KafkaJSDeleteGroupsErrorGroups[]);
}
export declare class KafkaJSDeleteTopicRecordsError extends KafkaJSError {
constructor(metadata: KafkaJSDeleteTopicRecordsErrorTopic);
}
export interface KafkaJSDeleteGroupsErrorGroups {
groupId: string;
errorCode: number;
error: KafkaJSError;
}
export interface KafkaJSDeleteTopicRecordsErrorTopic {
topic: string;
partitions: KafkaJSDeleteTopicRecordsErrorPartition[];
}
export interface KafkaJSDeleteTopicRecordsErrorPartition {
partition: number;
offset: string;
error: KafkaJSError;
}
export interface KafkaJSErrorMetadata {
retriable?: boolean;
topic?: string;
partitionId?: number;
metadata?: PartitionMetadata;
}
export interface KafkaJSOffsetOutOfRangeMetadata {
topic: string;
partition: number;
}
export interface KafkaJSNumberOfRetriesExceededMetadata {
retryCount: number;
retryTime: number;
}
export interface KafkaJSConnectionErrorMetadata {
broker?: string;
code?: string;
}
export interface KafkaJSRequestTimeoutErrorMetadata {
broker: string;
clientId: string;
correlationId: number;
createdAt: number;
sentAt: number;
pendingDuration: number;
}
export interface KafkaJSTopicMetadataNotLoadedMetadata {
topic: string;
}
export interface KafkaJSStaleTopicMetadataAssignmentMetadata {
topic: string;
unknownPartitions: PartitionMetadata[];
}
export interface KafkaJSServerDoesNotSupportApiKeyMetadata {
apiKey: number;
apiName: string;
}

View File

@@ -9,3 +9,22 @@ export interface RmqUrl {
heartbeat?: number;
vhost?: string;
}
export interface AmqpConnectionManagerSocketOptions {
reconnectTimeInSeconds?: number;
heartbeatIntervalInSeconds?: number;
findServers?: () => string | string[];
connectionOptions?: any;
}
export interface AmqplibQueueOptions {
durable?: boolean;
autoDelete?: boolean;
arguments?: any;
messageTtl?: number;
expires?: number;
deadLetterExchange?: string;
deadLetterRoutingKey?: string;
maxLength?: number;
maxPriority?: number;
}

View File

@@ -1,4 +1,4 @@
export * from './json-socket';
export * from './kafka-logger';
export * from './kafka-parser';
export * from './kafka-round-robin-partition-assigner';
export * from './kafka-reply-partition-assigner';

View File

@@ -0,0 +1,202 @@
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import { ClientKafka } from '../client/client-kafka';
import {
Cluster,
GroupMember,
GroupMemberAssignment,
GroupState,
MemberMetadata,
} from '../external/kafka.interface';
let kafkaPackage: any = {};
export class KafkaReplyPartitionAssigner {
readonly name = 'NestReplyPartitionAssigner';
readonly version = 1;
constructor(
private readonly clientKafka: ClientKafka,
private readonly config: {
cluster: Cluster;
},
) {
kafkaPackage = loadPackage(
'kafkajs',
KafkaReplyPartitionAssigner.name,
() => require('kafkajs'),
);
}
/**
* This process can result in imbalanced assignments
* @param {array} members array of members, e.g: [{ memberId: 'test-5f93f5a3' }]
* @param {array} topics
* @param {Buffer} userData
* @returns {array} object partitions per topic per member
*/
public async assign(group: {
members: GroupMember[];
topics: string[];
}): Promise<GroupMemberAssignment[]> {
const assignment = {};
const previousAssignment = {};
const membersCount = group.members.length;
const decodedMembers = group.members.map(member =>
this.decodeMember(member),
);
const sortedMemberIds = decodedMembers
.map(member => member.memberId)
.sort();
// build the previous assignment and an inverse map of topic > partition > memberId for lookup
decodedMembers.forEach(member => {
if (
!previousAssignment[member.memberId] &&
Object.keys(member.previousAssignment).length > 0
) {
previousAssignment[member.memberId] = member.previousAssignment;
}
});
// build a collection of topics and partitions
const topicsPartitions = group.topics
.map(topic => {
const partitionMetadata = this.config.cluster.findTopicPartitionMetadata(
topic,
);
return partitionMetadata.map(m => {
return {
topic,
partitionId: m.partitionId,
};
});
})
.reduce((acc, val) => acc.concat(val), []);
// create the new assignment by populating the members with the first partition of the topics
sortedMemberIds.forEach(assignee => {
if (!assignment[assignee]) {
assignment[assignee] = {};
}
// add topics to each member
group.topics.forEach(topic => {
if (!assignment[assignee][topic]) {
assignment[assignee][topic] = [];
}
// see if the topic and partition belong to a previous assignment
if (
previousAssignment[assignee] &&
!isUndefined(previousAssignment[assignee][topic])
) {
// take the minimum partition since replies will be sent to the minimum partition
const firstPartition = previousAssignment[assignee][topic];
// create the assignment with the first partition
assignment[assignee][topic].push(firstPartition);
// find and remove this topic and partition from the topicPartitions to be assigned later
const topicsPartitionsIndex = topicsPartitions.findIndex(
topicPartition => {
return (
topicPartition.topic === topic &&
topicPartition.partitionId === firstPartition
);
},
);
// only continue if we found a partition matching this topic
if (topicsPartitionsIndex !== -1) {
// remove inline
topicsPartitions.splice(topicsPartitionsIndex, 1);
}
}
});
});
// check for member topics that have a partition length of 0
sortedMemberIds.forEach(assignee => {
group.topics.forEach(topic => {
// only continue if there are no partitions for assignee's topic
if (assignment[assignee][topic].length === 0) {
// find the first partition for this topic
const topicsPartitionsIndex = topicsPartitions.findIndex(
topicPartition => {
return topicPartition.topic === topic;
},
);
if (topicsPartitionsIndex !== -1) {
// find and set the topic partition
const partition =
topicsPartitions[topicsPartitionsIndex].partitionId;
assignment[assignee][topic].push(partition);
// remove this partition from the topics partitions collection
topicsPartitions.splice(topicsPartitionsIndex, 1);
}
}
});
});
// then balance out the rest of the topic partitions across the members
const insertAssignmentsByTopic = (topicPartition, i) => {
const assignee = sortedMemberIds[i % membersCount];
assignment[assignee][topicPartition.topic].push(
topicPartition.partitionId,
);
};
// build the assignments
topicsPartitions.forEach(insertAssignmentsByTopic);
// encode the end result
return Object.keys(assignment).map(memberId => ({
memberId,
memberAssignment: kafkaPackage.AssignerProtocol.MemberAssignment.encode({
version: this.version,
assignment: assignment[memberId],
}),
}));
}
public protocol(subscription: {
topics: string[];
userData: Buffer;
}): GroupState {
const stringifiedUserData = JSON.stringify({
previousAssignment: this.getPreviousAssignment(),
});
subscription.userData = Buffer.from(stringifiedUserData);
return {
name: this.name,
metadata: kafkaPackage.AssignerProtocol.MemberMetadata.encode({
version: this.version,
topics: subscription.topics,
userData: subscription.userData,
}),
};
}
public getPreviousAssignment() {
return this.clientKafka.getConsumerAssignments();
}
public decodeMember(member: GroupMember) {
const memberMetadata = kafkaPackage.AssignerProtocol.MemberMetadata.decode(
member.memberMetadata,
) as MemberMetadata;
const memberUserData = JSON.parse(memberMetadata.userData.toString());
return {
memberId: member.memberId,
previousAssignment: memberUserData.previousAssignment,
};
}
}

View File

@@ -1,119 +0,0 @@
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import {
Cluster,
GroupMember,
GroupMemberAssignment,
GroupState,
MemberMetadata,
} from '../external/kafka.interface';
let kafkaPackage: any = {};
const time = process.hrtime();
export class KafkaRoundRobinPartitionAssigner {
readonly name = 'RoundRobinByTime';
readonly version = 1;
constructor(private readonly config: { cluster: Cluster }) {
kafkaPackage = loadPackage(
'kafkajs',
KafkaRoundRobinPartitionAssigner.name,
() => require('kafkajs'),
);
}
/**
* This process can result in imbalanced assignments
* @param {array} members array of members, e.g: [{ memberId: 'test-5f93f5a3' }]
* @param {array} topics
* @param {Buffer} userData
* @returns {array} object partitions per topic per member
*/
public async assign(group: {
members: GroupMember[];
topics: string[];
userData: Buffer;
}): Promise<GroupMemberAssignment[]> {
const membersCount = group.members.length;
const assignment = {};
const sortedMembers = group.members
.map(member => this.mapToTimeAndMemberId(member))
.sort((a, b) => this.sortByTime(a, b))
.map(member => member.memberId);
sortedMembers.forEach(memberId => {
assignment[memberId] = {};
});
const insertAssignmentsByTopic = (topic: string) => {
const partitionMetadata = this.config.cluster.findTopicPartitionMetadata(
topic,
);
const partitions = partitionMetadata.map(m => m.partitionId);
sortedMembers.forEach((memberId, i) => {
if (!assignment[memberId][topic]) {
assignment[memberId][topic] = [];
}
assignment[memberId][topic].push(
...partitions.filter(id => id % membersCount === i),
);
});
};
group.topics.forEach(insertAssignmentsByTopic);
return Object.keys(assignment).map(memberId => ({
memberId,
memberAssignment: kafkaPackage.AssignerProtocol.MemberAssignment.encode({
version: this.version,
assignment: assignment[memberId],
userData: group.userData,
}),
}));
}
public protocol(subscription: {
topics: string[];
userData: Buffer;
}): GroupState {
const stringifiedTimeObject = JSON.stringify({
time: this.getTime(),
});
subscription.userData = Buffer.from(stringifiedTimeObject);
return {
name: this.name,
metadata: kafkaPackage.AssignerProtocol.MemberMetadata.encode({
version: this.version,
topics: subscription.topics,
userData: subscription.userData,
}),
};
}
public getTime(): [number, number] {
return time;
}
public mapToTimeAndMemberId(member: GroupMember) {
const memberMetadata = kafkaPackage.AssignerProtocol.MemberMetadata.decode(
member.memberMetadata,
) as MemberMetadata;
const memberUserData = JSON.parse(memberMetadata.userData.toString());
return {
memberId: member.memberId,
time: memberUserData.time,
};
}
public sortByTime(a: Record<'time', number[]>, b: Record<'time', number[]>) {
// if seconds are equal sort by nanoseconds
if (a.time[0] === b.time[0]) {
return a.time[1] - b.time[1];
}
// sort by seconds
return a.time[0] - b.time[0];
}
}

View File

@@ -1,3 +1,5 @@
import { Type } from '@nestjs/common';
import { ClientProxy } from '../client';
import { Transport } from '../enums/transport.enum';
import { Deserializer } from './deserializer.interface';
import {
@@ -19,6 +21,11 @@ export type ClientOptions =
| TcpClientOptions
| RmqOptions;
export interface CustomClientOptions {
customClass: Type<ClientProxy>;
options?: Record<string, any>;
}
export interface TcpClientOptions {
transport: Transport.TCP;
options?: {

View File

@@ -1,18 +1,20 @@
import { Transport } from '../enums/transport.enum';
import { ChannelOptions } from '../external/grpc-options.interface';
import {
CompressionTypes,
ConsumerConfig,
ConsumerRunConfig,
ConsumerSubscribeTopic,
KafkaConfig,
ProducerConfig,
} from '../external/kafka-options.interface';
ProducerRecord,
} from '../external/kafka.interface';
import { MqttClientOptions } from '../external/mqtt-options.interface';
import { ClientOpts } from '../external/redis.interface';
import { RmqUrl } from '../external/rmq-url.interface';
import { Server } from '../server/server';
import { CustomTransportStrategy } from './custom-transport-strategy.interface';
import { Deserializer } from './deserializer.interface';
import { Serializer } from './serializer.interface';
import { RmqUrl } from '../external/rmq-url.interface';
export type MicroserviceOptions =
| GrpcOptions
@@ -25,7 +27,7 @@ export type MicroserviceOptions =
| CustomStrategy;
export interface CustomStrategy {
strategy: Server & CustomTransportStrategy;
strategy: CustomTransportStrategy;
options?: {};
}
@@ -101,13 +103,19 @@ export interface MqttOptions {
export interface NatsOptions {
transport?: Transport.NATS;
options?: {
encoding?: string;
url?: string;
name?: string;
user?: string;
pass?: string;
maxPingOut?: number;
maxReconnectAttempts?: number;
reconnectTimeWait?: number;
reconnectJitter?: number;
reconnectJitterTLS?: number;
reconnectDelayHandler?: any;
servers?: string[];
nkey?: any;
reconnect?: boolean;
pedantic?: boolean;
tls?: any;
@@ -117,6 +125,18 @@ export interface NatsOptions {
userJWT?: string;
nonceSigner?: any;
userCreds?: any;
useOldRequestStyle?: boolean;
pingInterval?: number;
preserveBuffers?: boolean;
waitOnFirstConnect?: boolean;
verbose?: boolean;
noEcho?: boolean;
noRandomize?: boolean;
timeout?: number;
token?: string;
yieldTime?: number;
tokenHandler?: any;
[key: string]: any;
};
}
@@ -127,8 +147,8 @@ export interface RmqOptions {
queue?: string;
prefetchCount?: number;
isGlobalPrefetchCount?: boolean;
queueOptions?: any;
socketOptions?: any;
queueOptions?: any; // AmqplibQueueOptions;
socketOptions?: any; // AmqpConnectionManagerSocketOptions;
noAck?: boolean;
serializer?: Serializer;
deserializer?: Deserializer;
@@ -140,24 +160,13 @@ export interface RmqOptions {
export interface KafkaOptions {
transport?: Transport.KAFKA;
options?: {
postfixId?: string;
client?: KafkaConfig;
consumer?: ConsumerConfig;
run?: {
autoCommit?: boolean;
autoCommitInterval?: number | null;
autoCommitThreshold?: number | null;
eachBatchAutoResolve?: boolean;
partitionsConsumedConcurrently?: number;
};
subscribe?: {
fromBeginning?: boolean;
};
run?: Omit<ConsumerRunConfig, 'eachBatch' | 'eachMessage'>;
subscribe?: Omit<ConsumerSubscribeTopic, 'topic'>;
producer?: ProducerConfig;
send?: {
acks?: number;
timeout?: number;
compression?: CompressionTypes;
};
send?: Omit<ProducerRecord, 'topic' | 'messages'>;
serializer?: Serializer;
deserializer?: Deserializer;
};

View File

@@ -1,21 +1,23 @@
import { ClientOptions } from '../../interfaces';
import { ClientOptions, CustomClientOptions } from '../../interfaces';
import { Type, Provider, ModuleMetadata } from '@nestjs/common/interfaces';
export type ClientProviderOptions = ClientOptions & {
export type ClientProvider = ClientOptions | CustomClientOptions;
export type ClientProviderOptions = ClientProvider & {
name: string | symbol;
};
export type ClientsModuleOptions = Array<ClientProviderOptions>;
export interface ClientsModuleOptionsFactory {
createClientOptions(): Promise<ClientOptions> | ClientOptions;
createClientOptions(): Promise<ClientProvider> | ClientProvider;
}
export interface ClientsProviderAsyncOptions
extends Pick<ModuleMetadata, 'imports'> {
useExisting?: Type<ClientsModuleOptionsFactory>;
useClass?: Type<ClientsModuleOptionsFactory>;
useFactory?: (...args: any[]) => Promise<ClientOptions> | ClientOptions;
useFactory?: (...args: any[]) => Promise<ClientProvider> | ClientProvider;
inject?: any[];
extraProviders?: Provider[];
name: string | symbol;

View File

@@ -123,7 +123,7 @@ export class NestMicroservice
!this.isInitialized && (await this.registerModules());
this.logger.log(MESSAGES.MICROSERVICE_READY);
return new Promise(resolve => this.server.listen(resolve));
return new Promise<void>(resolve => this.server.listen(resolve));
}
public async close(): Promise<any> {

View File

@@ -1,6 +1,6 @@
{
"name": "@nestjs/microservices",
"version": "7.5.5",
"version": "7.6.10",
"description": "Nest - modern, fast, powerful node.js web framework (@microservices)",
"author": "Kamil Mysliwiec",
"license": "MIT",
@@ -19,15 +19,54 @@
"dependencies": {
"iterare": "1.2.1",
"json-socket": "0.3.0",
"tslib": "2.0.3"
"tslib": "2.1.0"
},
"devDependencies": {
"@nestjs/common": "7.5.5",
"@nestjs/core": "7.5.5"
"@nestjs/common": "7.6.10",
"@nestjs/core": "7.6.10"
},
"peerDependencies": {
"@nestjs/common": "^7.0.0",
"@nestjs/core": "^7.0.0",
"@nestjs/websockets": "^7.0.0",
"amqp-connection-manager": "*",
"amqplib": "*",
"cache-manager": "*",
"grpc": "*",
"kafkajs": "*",
"mqtt": "*",
"nats": "*",
"redis": "*",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0"
},
"peerDependenciesMeta": {
"@nestjs/websockets": {
"optional": true
},
"cache-manager": {
"optional": true
},
"grpc": {
"optional": true
},
"kafkajs": {
"optional": true
},
"mqtt": {
"optional": true
},
"nats": {
"optional": true
},
"redis": {
"optional": true
},
"amqplib": {
"optional": true
},
"amqp-connection-manager": {
"optional": true
}
}
}

View File

@@ -19,6 +19,7 @@ import {
KafkaMessage,
Message,
Producer,
RecordMetadata,
} from '../external/kafka.interface';
import { KafkaLogger, KafkaParser } from '../helpers';
import {
@@ -50,17 +51,16 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
this.getOptionsProp(this.options, 'client') || ({} as KafkaConfig);
const consumerOptions =
this.getOptionsProp(this.options, 'consumer') || ({} as ConsumerConfig);
const postfixId =
this.getOptionsProp(this.options, 'postfixId') || '-server';
this.brokers = clientOptions.brokers || [KAFKA_DEFAULT_BROKER];
// append a unique id to the clientId and groupId
// so they don't collide with a microservices client
this.clientId =
(clientOptions.clientId || KAFKA_DEFAULT_CLIENT) +
(clientOptions.clientIdPostfix || '-server');
this.groupId =
(consumerOptions.groupId || KAFKA_DEFAULT_GROUP) +
(clientOptions.clientIdPostfix || '-server');
(clientOptions.clientId || KAFKA_DEFAULT_CLIENT) + postfixId;
this.groupId = (consumerOptions.groupId || KAFKA_DEFAULT_GROUP) + postfixId;
kafkaPackage = this.loadPackage('kafkajs', ServerKafka.name, () =>
require('kafkajs'),
@@ -75,9 +75,9 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
await this.start(callback);
}
public close(): void {
this.consumer && this.consumer.disconnect();
this.producer && this.producer.disconnect();
public async close(): Promise<void> {
this.consumer && (await this.consumer.disconnect());
this.producer && (await this.producer.disconnect());
this.consumer = null;
this.producer = null;
this.client = null;
@@ -130,7 +130,7 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
replyTopic: string,
replyPartition: string,
correlationId: string,
): (data: any) => any {
): (data: any) => Promise<RecordMetadata[]> {
return (data: any) =>
this.sendMessage(data, replyTopic, replyPartition, correlationId);
}
@@ -184,7 +184,7 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
replyTopic: string,
replyPartition: string,
correlationId: string,
): void {
): Promise<RecordMetadata[]> {
const outgoingMessage = this.serializer.serialize(message.response);
this.assignReplyPartition(replyPartition, outgoingMessage);
this.assignCorrelationIdHeader(correlationId, outgoingMessage);
@@ -198,7 +198,7 @@ export class ServerKafka extends Server implements CustomTransportStrategy {
},
this.options.send || {},
);
this.producer.send(replyMessage);
return this.producer.send(replyMessage);
}
public assignIsDisposedHeader(

View File

@@ -18,13 +18,13 @@ import {
} from '../constants';
import { RmqContext } from '../ctx-host';
import { Transport } from '../enums';
import { RmqUrl } from '../external/rmq-url.interface';
import { CustomTransportStrategy, RmqOptions } from '../interfaces';
import {
IncomingRequest,
OutgoingResponse,
} from '../interfaces/packet.interface';
import { Server } from './server';
import { RmqUrl } from '../external/rmq-url.interface';
let rqmPackage: any = {};

View File

@@ -61,14 +61,16 @@ export abstract class Server {
public send(
stream$: Observable<any>,
respond: (data: WritePacket) => void,
respond: (data: WritePacket) => unknown | Promise<unknown>,
): Subscription {
let dataBuffer: WritePacket[] = null;
const scheduleOnNextTick = (data: WritePacket) => {
if (!dataBuffer) {
dataBuffer = [data];
process.nextTick(() => {
dataBuffer.forEach(buffer => respond(buffer));
process.nextTick(async () => {
for (const item of dataBuffer) {
await respond(item);
}
dataBuffer = null;
});
} else if (!data.isDisposed) {

View File

@@ -3,7 +3,6 @@ import * as sinon from 'sinon';
import { ClientKafka } from '../../client/client-kafka';
import { NO_MESSAGE_HANDLER } from '../../constants';
import { KafkaHeaders } from '../../enums';
import { InvalidKafkaClientTopicPartitionException } from '../../errors/invalid-kafka-client-topic-partition.exception';
import { InvalidKafkaClientTopicException } from '../../errors/invalid-kafka-client-topic.exception';
import {
ConsumerGroupJoinEvent,
@@ -269,6 +268,7 @@ describe('ClientKafka', () => {
expect(createClientStub.calledOnce).to.be.true;
expect(producerStub.calledOnce).to.be.true;
expect(consumerStub.calledOnce).to.be.true;
expect(on.calledOnce).to.be.true;
@@ -314,13 +314,19 @@ describe('ClientKafka', () => {
memberId: 'member-1',
memberAssignment: {
'topic-a': [0, 1, 2],
'topic-b': [3, 4, 5],
},
},
};
client['setConsumerAssignments'](consumerAssignments);
expect(client['consumerAssignments']).to.deep.eq(
consumerAssignments.payload.memberAssignment,
// consumerAssignments.payload.memberAssignment,
{
'topic-a': 0,
'topic-b': 3,
},
);
});
});
@@ -493,10 +499,22 @@ describe('ClientKafka', () => {
});
});
describe('getConsumerAssignments', () => {
it('should get consumer assignments', () => {
client['consumerAssignments'] = {
[replyTopic]: 0,
};
const result = client.getConsumerAssignments();
expect(result).to.deep.eq(client['consumerAssignments']);
});
});
describe('getReplyTopicPartition', () => {
it('should get reply partition', () => {
client['consumerAssignments'] = {
[replyTopic]: [0],
[replyTopic]: 0,
};
const result = client['getReplyTopicPartition'](replyTopic);
@@ -504,19 +522,17 @@ describe('ClientKafka', () => {
expect(result).to.eq('0');
});
it('should throw error when the topic is being consumed but is not assigned partitions', () => {
client['consumerAssignments'] = {
[replyTopic]: [],
};
it('should throw error when the topic is not being consumed', () => {
client['consumerAssignments'] = {};
expect(() => client['getReplyTopicPartition'](replyTopic)).to.throw(
InvalidKafkaClientTopicPartitionException,
InvalidKafkaClientTopicException,
);
});
it('should throw error when the topic is not being consumer', () => {
it('should throw error when the topic is not being consumed', () => {
client['consumerAssignments'] = {
[topic]: [],
[topic]: undefined,
};
expect(() => client['getReplyTopicPartition'](replyTopic)).to.throw(
@@ -551,7 +567,7 @@ describe('ClientKafka', () => {
'getReplyTopicPartition',
);
routingMapSetSpy = sinon.spy((client as any).routingMap, 'set');
sendSpy = sinon.spy();
sendSpy = sinon.spy(() => Promise.resolve());
// stub
assignPacketIdStub = sinon
@@ -568,7 +584,7 @@ describe('ClientKafka', () => {
// set
client['consumerAssignments'] = {
[replyTopic]: [parseFloat(replyPartition)],
[replyTopic]: parseFloat(replyPartition),
};
});

View File

@@ -0,0 +1,286 @@
import { expect } from 'chai';
import * as sinon from 'sinon';
import * as Kafka from 'kafkajs';
import { KafkaReplyPartitionAssigner } from '../../helpers/kafka-reply-partition-assigner';
import { ClientKafka } from '../../client/client-kafka';
describe('kafka reply partition assigner', () => {
let cluster, topics, metadata, assigner, client;
let getConsumerAssignments: sinon.SinonSpy;
let getPreviousAssignment: sinon.SinonSpy;
beforeEach(() => {
metadata = {};
cluster = { findTopicPartitionMetadata: topic => metadata[topic] };
client = new ClientKafka({});
assigner = new KafkaReplyPartitionAssigner(client, { cluster });
topics = ['topic-A', 'topic-B'];
getConsumerAssignments = sinon.spy(client, 'getConsumerAssignments');
getPreviousAssignment = sinon.spy(assigner, 'getPreviousAssignment');
// reset previous assignments
(client as any).consumerAssignments = {};
});
describe('assign', () => {
it('assign all partitions evenly', async () => {
metadata['topic-A'] = Array(14)
.fill(1)
.map((_, i) => ({ partitionId: i }));
metadata['topic-B'] = Array(5)
.fill(1)
.map((_, i) => ({ partitionId: i }));
const members = [
{
memberId: 'member-3',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {},
}),
),
}),
},
{
memberId: 'member-1',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {},
}),
),
}),
},
{
memberId: 'member-4',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {},
}),
),
}),
},
{
memberId: 'member-2',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {},
}),
),
}),
},
];
const assignment = await assigner.assign({ members, topics });
expect(assignment).to.deep.equal([
{
memberId: 'member-1',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [0, 4, 8, 12],
'topic-B': [0],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-2',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [1, 5, 9, 13],
'topic-B': [1],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-3',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [2, 6, 10],
'topic-B': [2, 4],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-4',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [3, 7, 11],
'topic-B': [3],
},
userData: Buffer.alloc(0),
}),
},
]);
});
});
describe('re-assign', () => {
it('assign all partitions evenly', async () => {
metadata['topic-A'] = Array(11)
.fill(1)
.map((_, i) => ({ partitionId: i }));
metadata['topic-B'] = Array(7)
.fill(1)
.map((_, i) => ({ partitionId: i }));
const members = [
{
memberId: 'member-3',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {
'topic-A': 0,
'topic-B': 0,
},
}),
),
}),
},
{
memberId: 'member-1',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {
'topic-A': 1,
'topic-B': 1,
},
}),
),
}),
},
{
memberId: 'member-4',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {
'topic-A': 2,
},
}),
),
}),
},
{
memberId: 'member-2',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
previousAssignment: {},
}),
),
}),
},
];
const assignment = await assigner.assign({ members, topics });
expect(assignment).to.deep.equal([
{
memberId: 'member-1',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [1, 4, 8],
'topic-B': [1, 5],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-2',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [3, 5, 9],
'topic-B': [2, 6],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-3',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [0, 6, 10],
'topic-B': [0],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-4',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [2, 7],
'topic-B': [3, 4],
},
userData: Buffer.alloc(0),
}),
},
]);
});
});
describe('protocol', () => {
it('returns the assigner name and metadata', () => {
// set previous assignments
(client as any).consumerAssignments = {
'topic-A': 0,
'topic-B': 1,
};
const protocol = assigner.protocol({ topics });
expect(getPreviousAssignment.calledOnce).to.be.true;
expect(getConsumerAssignments.calledOnce).to.be.true;
expect(protocol).to.deep.equal({
name: assigner.name,
metadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics,
userData: Buffer.from(
JSON.stringify({
previousAssignment: (client as any).consumerAssignments,
}),
),
}),
});
});
});
});

View File

@@ -1,143 +0,0 @@
import { expect } from 'chai';
import * as Kafka from 'kafkajs';
import { KafkaRoundRobinPartitionAssigner } from '../../helpers/kafka-round-robin-partition-assigner';
describe('kafka round robin by time', () => {
let cluster, topics, metadata, assigner;
beforeEach(() => {
metadata = {};
cluster = { findTopicPartitionMetadata: topic => metadata[topic] };
assigner = new KafkaRoundRobinPartitionAssigner({ cluster });
topics = ['topic-A', 'topic-B'];
});
describe('assign', () => {
it('assign all partitions evenly', async () => {
metadata['topic-A'] = Array(14)
.fill(1)
.map((_, i) => ({ partitionId: i }));
metadata['topic-B'] = Array(5)
.fill(1)
.map((_, i) => ({ partitionId: i }));
const members = [
{
memberId: 'member-3',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
time: [0, 0], // process.hrtime()
}),
),
}),
},
{
memberId: 'member-1',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
time: [0, 1], // process.hrtime()
}),
),
}),
},
{
memberId: 'member-4',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
time: [1, 1], // process.hrtime()
}),
),
}),
},
{
memberId: 'member-2',
memberMetadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics: ['topic-A', 'topic-B'],
userData: Buffer.from(
JSON.stringify({
time: [2, 0], // process.hrtime()
}),
),
}),
},
];
const assignment = await assigner.assign({ members, topics });
expect(assignment).to.deep.equal([
{
memberId: 'member-3',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [0, 4, 8, 12],
'topic-B': [0, 4],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-1',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [1, 5, 9, 13],
'topic-B': [1],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-4',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [2, 6, 10],
'topic-B': [2],
},
userData: Buffer.alloc(0),
}),
},
{
memberId: 'member-2',
memberAssignment: Kafka.AssignerProtocol.MemberAssignment.encode({
version: assigner.version,
assignment: {
'topic-A': [3, 7, 11],
'topic-B': [3],
},
userData: Buffer.alloc(0),
}),
},
]);
});
});
describe('protocol', () => {
it('returns the assigner name and metadata', () => {
expect(assigner.protocol({ topics })).to.deep.equal({
name: assigner.name,
metadata: Kafka.AssignerProtocol.MemberMetadata.encode({
version: assigner.version,
topics,
userData: Buffer.from(
JSON.stringify({
time: assigner.getTime(),
}),
),
}),
});
});
});
});

View File

@@ -21,7 +21,7 @@ describe('JsonSocket connection', () => {
new Promise(callback => {
clientSocket.sendMessage({ type: 'ping' }, callback);
}),
new Promise(callback => {
new Promise<void>(callback => {
clientSocket.on(MESSAGE_EVENT, (message: string) => {
expect(message).to.deep.equal({ type: 'pong' });
callback();
@@ -53,16 +53,16 @@ describe('JsonSocket connection', () => {
expect(clientSocket['isClosed']).to.equal(false);
expect(serverSocket['isClosed']).to.equal(false);
Promise.all([
new Promise(callback => {
new Promise<void>(callback => {
clientSocket.sendMessage(longPayload, callback);
}),
new Promise(callback => {
new Promise<void>(callback => {
clientSocket.on(MESSAGE_EVENT, (message: { type: 'pong' }) => {
expect(message).to.deep.equal({ type: 'pong' });
callback();
});
}),
new Promise(callback => {
new Promise<void>(callback => {
serverSocket.on(MESSAGE_EVENT, (message: { type: 'pong' }) => {
expect(message).to.deep.equal(longPayload);
serverSocket.sendMessage({ type: 'pong' }, callback);
@@ -85,7 +85,7 @@ describe('JsonSocket connection', () => {
return done(err);
}
Promise.all([
new Promise(callback =>
new Promise<void>(callback =>
Promise.all(
helpers
.range(1, 100)
@@ -97,7 +97,7 @@ describe('JsonSocket connection', () => {
),
).then(_ => callback()),
),
new Promise(callback => {
new Promise<void>(callback => {
let lastNumber = 0;
serverSocket.on(MESSAGE_EVENT, (message: { number: number }) => {
expect(message.number).to.deep.equal(lastNumber + 1);
@@ -128,7 +128,7 @@ describe('JsonSocket connection', () => {
})
.then(
() =>
new Promise(callback => {
new Promise<void>(callback => {
expect(clientSocket['isClosed']).to.equal(true);
expect(serverSocket['isClosed']).to.equal(true);
callback();
@@ -154,7 +154,7 @@ describe('JsonSocket connection', () => {
})
.then(
() =>
new Promise(callback => {
new Promise<void>(callback => {
expect(clientSocket['isClosed']).to.equal(true);
expect(serverSocket['isClosed']).to.equal(true);
callback();

Some files were not shown because too many files have changed in this diff Show More