mirror of
https://github.com/nestjs/nest.git
synced 2026-02-24 00:02:56 +00:00
Compare commits
2 Commits
v10.3.5
...
fix/fastif
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5612e0197 | ||
|
|
6c54448bf7 |
@@ -1,31 +1,9 @@
|
||||
version: 2.1
|
||||
|
||||
parameters:
|
||||
check-legacy-node-version:
|
||||
type: boolean
|
||||
default: false
|
||||
legacy-node-version:
|
||||
type: string
|
||||
default: '14.21.3'
|
||||
maintenance-node-version:
|
||||
type: string
|
||||
default: '16.20'
|
||||
active-node-version:
|
||||
type: string
|
||||
default: '18.17'
|
||||
current-node-version:
|
||||
type: string
|
||||
default: '20.5'
|
||||
version: 2
|
||||
|
||||
aliases:
|
||||
- &restore-cache
|
||||
restore_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
- &save-cache
|
||||
save_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- &install-deps
|
||||
run:
|
||||
name: Install dependencies
|
||||
@@ -39,89 +17,70 @@ aliases:
|
||||
name: Test
|
||||
command: npm run test
|
||||
|
||||
unit-tests-template: &unit-tests-template
|
||||
working_directory: ~/nest
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
- *install-deps
|
||||
- *build-packages
|
||||
- *run-unit-tests
|
||||
|
||||
jobs:
|
||||
build:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< pipeline.parameters.maintenance-node-version >>
|
||||
- image: cimg/node:16.19
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update NPM version
|
||||
command: 'sudo npm install -g npm@^9'
|
||||
- *restore-cache
|
||||
- *install-deps
|
||||
- *save-cache
|
||||
- *build-packages
|
||||
command: 'sudo npm install -g npm@^8'
|
||||
- restore_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm ci --legacy-peer-deps
|
||||
- save_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- run:
|
||||
name: Build
|
||||
command: npm run build
|
||||
|
||||
test:
|
||||
parameters:
|
||||
node-version:
|
||||
type: string
|
||||
test_node_16:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< parameters.node-version >>
|
||||
- image: cimg/node:16.19
|
||||
steps:
|
||||
- when:
|
||||
condition:
|
||||
and:
|
||||
- equal:
|
||||
[
|
||||
'<< parameters.node-version >>',
|
||||
'<< pipeline.parameters.legacy-node-version >>',
|
||||
]
|
||||
- not: << pipeline.parameters.check-legacy-node-version >>
|
||||
steps:
|
||||
- run:
|
||||
name: Skip
|
||||
command: |
|
||||
echo Skipping
|
||||
- when:
|
||||
condition:
|
||||
or:
|
||||
- not:
|
||||
equal:
|
||||
[
|
||||
'<< parameters.node-version >>',
|
||||
'<< pipeline.parameters.legacy-node-version >>',
|
||||
]
|
||||
- << pipeline.parameters.check-legacy-node-version >>
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
- *install-deps
|
||||
- *build-packages
|
||||
- when:
|
||||
condition:
|
||||
equal:
|
||||
[
|
||||
'<< parameters.node-version >>',
|
||||
'<< pipeline.parameters.maintenance-node-version >>',
|
||||
]
|
||||
steps:
|
||||
- run:
|
||||
name: Test (coverage)
|
||||
command: npm run test:cov
|
||||
- run:
|
||||
name: Collect coverage
|
||||
command: npm run coverage
|
||||
- store_artifacts:
|
||||
path: coverage
|
||||
- when:
|
||||
condition:
|
||||
not:
|
||||
equal:
|
||||
[
|
||||
'<< parameters.node-version >>',
|
||||
'<< pipeline.parameters.maintenance-node-version >>',
|
||||
]
|
||||
steps:
|
||||
- *run-unit-tests
|
||||
- checkout
|
||||
- *restore-cache
|
||||
- *install-deps
|
||||
- *build-packages
|
||||
- run:
|
||||
name: Test (coverage)
|
||||
command: npm run test:cov
|
||||
- run:
|
||||
name: Collect coverage
|
||||
command: npm run coverage
|
||||
- store_artifacts:
|
||||
path: coverage
|
||||
|
||||
test_node_18:
|
||||
<<: *unit-tests-template
|
||||
docker:
|
||||
- image: cimg/node:18.14
|
||||
|
||||
test_node_19:
|
||||
<<: *unit-tests-template
|
||||
docker:
|
||||
- image: cimg/node:19.8
|
||||
|
||||
lint:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< pipeline.parameters.maintenance-node-version >>
|
||||
- image: circleci/node:16
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
@@ -146,9 +105,9 @@ jobs:
|
||||
- run:
|
||||
name: Upgrade Node.js
|
||||
command: |
|
||||
nvm install << pipeline.parameters.maintenance-node-version >>
|
||||
nvm install v16
|
||||
node -v
|
||||
nvm alias default << pipeline.parameters.maintenance-node-version >>
|
||||
nvm alias default v16
|
||||
- run:
|
||||
name: Install Docker Compose
|
||||
command: |
|
||||
@@ -171,7 +130,7 @@ jobs:
|
||||
codechecks_benchmarks:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< pipeline.parameters.maintenance-node-version >>
|
||||
- image: cimg/node:16.19
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
@@ -187,9 +146,9 @@ jobs:
|
||||
samples:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< pipeline.parameters.maintenance-node-version >>
|
||||
- image: cimg/node:16.19
|
||||
environment:
|
||||
DISABLE_OPENCOLLECTIVE: 'true'
|
||||
- DISABLE_OPENCOLLECTIVE: true
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
@@ -199,21 +158,16 @@ jobs:
|
||||
command: npm run build:samples
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-and-test:
|
||||
jobs:
|
||||
- build
|
||||
- test:
|
||||
- test_node_16:
|
||||
requires:
|
||||
- build
|
||||
- test_node_18:
|
||||
requires:
|
||||
- build
|
||||
matrix:
|
||||
parameters:
|
||||
node-version:
|
||||
[
|
||||
'<< pipeline.parameters.legacy-node-version >>',
|
||||
'<< pipeline.parameters.maintenance-node-version >>',
|
||||
'<< pipeline.parameters.active-node-version >>',
|
||||
'<< pipeline.parameters.current-node-version >>',
|
||||
]
|
||||
- lint:
|
||||
requires:
|
||||
- build
|
||||
|
||||
@@ -23,7 +23,6 @@ module.exports = {
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-array-constructor': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/Bug_report.yml
vendored
8
.github/ISSUE_TEMPLATE/Bug_report.yml
vendored
@@ -6,7 +6,7 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
||||
|
||||
|
||||
If you are not sure that your issue is a bug, you could:
|
||||
|
||||
- read the [FAQ's common errors](https://docs.nestjs.com/faq/common-errors) page
|
||||
@@ -38,9 +38,7 @@ body:
|
||||
required: true
|
||||
attributes:
|
||||
label: "Minimum reproduction code"
|
||||
description: |
|
||||
An URL to some Git repository/[StackBlitz](https://stackblitz.com/fork/github/nestjs/typescript-starter)/[CodeSandbox](https://codesandbox.io/s/github/nestjs/typescript-starter/tree/master) project that reproduces your issue. [What is a minimum reproduction?](https://jmcdo29.github.io/wtf-is-a-minimum-reproduction)
|
||||
:warning: **NOTE:** We can close this issue if we don't manage to reproduce your potential bug. [Here](https://antfu.me/posts/why-reproductions-are-required) is why.
|
||||
description: "An URL to some Git repository/[StackBlitz](https://stackblitz.com/fork/github/nestjs/typescript-starter)/[CodeSandbox](https://codesandbox.io/s/github/nestjs/typescript-starter/tree/master) project that reproduces your issue. [Wtf is a minimum reproduction?](https://jmcdo29.github.io/wtf-is-a-minimum-reproduction)"
|
||||
placeholder: "https://github.com/..."
|
||||
|
||||
- type: textarea
|
||||
@@ -48,7 +46,7 @@ body:
|
||||
label: "Steps to reproduce"
|
||||
description: |
|
||||
How the issue manifests?
|
||||
You could leave this blank if you already write this in your reproduction code
|
||||
You could leave this blank if you alread write this in your reproduction code
|
||||
placeholder: |
|
||||
1. `npm ci`
|
||||
2. `npm start:dev`
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/Feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/Feature_request.yml
vendored
@@ -6,7 +6,7 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
||||
|
||||
|
||||
If you are not sure that your issue is a bug, you could:
|
||||
|
||||
- read the [FAQ's common errors](https://docs.nestjs.com/faq/common-errors) page
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/Regression.yml
vendored
2
.github/ISSUE_TEMPLATE/Regression.yml
vendored
@@ -6,7 +6,7 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
||||
|
||||
|
||||
If you are not sure that your issue is a bug, you could:
|
||||
|
||||
- read the [FAQ's common errors](https://docs.nestjs.com/faq/common-errors) page
|
||||
|
||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
queries: +security-extended
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -58,4 +58,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,9 +6,6 @@ node_modules/
|
||||
/.awcache
|
||||
/.vscode
|
||||
/.devcontainer
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings
|
||||
*.code-workspace
|
||||
|
||||
# Vim
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install commitlint --edit $1
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
|
||||
@@ -164,7 +164,7 @@ You will need [Node.js](https://nodejs.org) version >= 10.13.0 (except for v13).
|
||||
1. After cloning the repo, run:
|
||||
|
||||
```bash
|
||||
$ npm ci --legacy-peer-deps # (or yarn install)
|
||||
$ npm ci # (or yarn install)
|
||||
```
|
||||
|
||||
2. In order to prepare your environment run `prepare.sh` shell script:
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017-2024 Kamil Mysliwiec <https://kamilmysliwiec.com>
|
||||
Copyright (c) 2017-2023 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
|
||||
|
||||
101
Readme.md
101
Readme.md
@@ -23,21 +23,21 @@
|
||||
|
||||
## Description
|
||||
|
||||
Nest is a framework for building efficient, scalable <a href="https://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="https://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
|
||||
Nest is a framework for building efficient, scalable <a href="http://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="http://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
|
||||
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also provides compatibility with a wide range of other libraries, like <a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>, allowing for easy use of the myriad of third-party plugins which are available.</p>
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also, provides compatibility with a wide range of other libraries, like e.g. <a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>, allowing for easy use of the myriad third-party plugins which are available.</p>
|
||||
|
||||
## Philosophy
|
||||
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a>, and <a href="https://github.com/vuejs/vue" target="_blank">Vue</a>, which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers, and tools for Node, none of them effectively solve the main problem - the architecture.</p>
|
||||
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, and loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a> and <a href="https://github.com/vuejs/vue" target="_blank">Vue</a> which improve developer productivity and enable the construction of fast, testable, extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers and tools for Node, none of them effectively solve the main problem - the architecture.</p>
|
||||
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>
|
||||
|
||||
## Getting started
|
||||
|
||||
- To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
- 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
- [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
|
||||
- [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
|
||||
* To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
* 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
* [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
|
||||
* [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
|
||||
|
||||
## Questions
|
||||
|
||||
@@ -56,42 +56,45 @@ With official support, you can get expert help straight from Nest core team. We
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support from the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
||||
#### Principal Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" 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="170" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/red-hat-logo.svg" width="200" valign="middle" /></a></td>
|
||||
<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://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" 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="170" valign="middle" /></a></td><td>
|
||||
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://weld.app/" target="_blank"><img src="https://nestjs.com/img/weld-logo.svg" width="140" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="90" valign="middle" /></a></td></tr><tr><td>
|
||||
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="110" valign="middle" /></a></td><td>
|
||||
<a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/snyk-logo-black.png" width="185" valign="middle" /></a></td><td>
|
||||
<a href="https://fuseautotech.com/" target="_blank"><img src="https://nestjs.com/img/fuse-logo.svg" width="105" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://ridicorp.com/career/" target="_blank"><img src="https://nestjs.com/img/ridi-logo.svg" width="105" valign="middle" /></a></td><td>
|
||||
<a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://nestjs.com/img/movavi-logo.svg" width="105" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://skunk.team" target="_blank"><img src="https://nestjs.com/img/skunk-logo.png" height="60" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
<a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://nestjs.com/img/movavi-logo.svg" width="105" valign="middle" /></a></td></</tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td>
|
||||
<td><a href="https://twistag.com/" target="_blank"><img src="https://nestjs.com/img/twistag-logo.png" width="120" valign="middle" /></td>
|
||||
</tr>
|
||||
<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://www.myleodsc.com/" target="_blank"><img src="https://nestjs.com/img/myleo-logo.png" width="180" valign="middle" /></td><td>
|
||||
<a href="https://careers.meetdandy.com/?gh_src=063ba61e3us" target="_blank"><img src="https://nestjs.com/img/dandy-roles-logo.svg" width="150" valign="middle" /></td><td>
|
||||
<a href="https://www.castlecraft.in" target="_blank"><img src="https://nestjs.com/img/castlecraft-logo.png" width="150" valign="middle" /></td>
|
||||
<td><a href="https://www.tinystacks.com" target="_blank"><img src="https://nestjs.com/img/tinystacks-logo.png#1" width="140" valign="middle" /></td>
|
||||
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td></tr><tr>
|
||||
<td><a href="https://bilberrry.com/" target="_blank"><img src="https://nestjs.com/img/bilberrry-logo.svg" width="180" valign="middle" /></td>
|
||||
<td><a href="https://ipinfo.ai/" target="_blank"><img src="https://nestjs.com/img/ipinfo-logo.png" width="130" valign="middle" /></td>
|
||||
<td><a href="https://chax.at" target="_blank"><img src="https://nestjs.com/img/chaxat-logo.png" width="100" valign="middle" /></td></tr>
|
||||
</table>
|
||||
|
||||
#### Sponsors
|
||||
@@ -99,26 +102,42 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<table><tr><td align="center" valign="middle">
|
||||
<a href="https://www.swingdev.io" target="_blank"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="110" valign="middle" /> </a></td><td align="center" valign="middle">
|
||||
<a href="https://www.novologic.com/" target="_blank"><img src="https://nestjs.com/img/novologic.png" width="110" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://ever.co/" target="_blank"><img src="https://nestjs.com/img/ever-logo.png" width="72" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://blokt.com" target="_blank"><img src="https://nestjs.com/img/blokt-logo.png" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="http://architectnow.net/" target="_blank"><img src="https://nestjs.com/img/architectnow.png" width="125" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://quander.io/" target="_blank"><img src="https://nestjs.com/img/quander.png" width="100" valign="middle" /></a> </td></tr><tr><td align="center" valign="middle">
|
||||
<a href="https://mantro.net/" target="_blank"><img src="https://nestjs.com/img/mantro-logo.svg" width="95" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://triplebyte.com/" target="_blank"><img src="https://nestjs.com/img/triplebyte.png" width="107" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td>
|
||||
<a href="https://reposit.co.uk/" target="_blank"><img src="https://nestjs.com/img/reposit-logo.png" width="71" valign="middle" /></a></td><td align="center" valign="middle">
|
||||
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://clay.global/" target="_blank"><img src="https://nestjs.com/img/clay-logo.svg" width="75" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://firesticktricks.com" target="_blank"><img src="https://nestjs.com/img/firesticktricks-logo.png" width="120" valign="middle" /></a></td></tr><tr><td align="center" valign="middle">
|
||||
<a href="https://www.codeguesser.co.uk" target="_blank"><img src="https://nestjs.com/img/codeguesser-logo.svg" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://f-a.nz/" target="_blank"><img src="https://nestjs.com/img/franz.svg" width="80" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://sparkfabrik.com/" target="_blank"><img src="https://nestjs.com/img/sparkfabrik-logo.png" width="120" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://www.thebigphonestore.co.uk/" target="_blank"><img src="https://nestjs.com/img/the-big-phone-store-logo.png" width="65" valign="middle" /></a></td>
|
||||
<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></tr><tr>
|
||||
<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><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://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<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://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></tr><tr>
|
||||
<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>
|
||||
<td align="center" valign="middle"><a href="https://houseofangular.io/" target="_blank"><img src="https://nestjs.com/img/house-of-angular.png" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://rocketech.it/cases/?utm_source=google&utm_medium=badge&utm_campaign=nestjs" target="_blank"><img src="https://nestjs.com/img/rocketech-logo.svg" width="110" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.bystored.com/" target="_blank"><img src="https://nestjs.com/img/stored-logo.svg" width="110" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://studyclerk.com/pay-for-research-paper" target="_blank"><img src="https://nestjs.com/img/studyclerk-logo.png" width="125" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://xyndata.com" target="_blank"><img src="https://nestjs.com/img/xyndata-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.naologic.com/" target="_blank"><img src="https://nestjs.com/img/naologic-logo.svg" width="125" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://messaged.com/" target="_blank"><img src="https://nestjs.com/img/messaged-logo.png" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://triplecore.io" target="_blank"><img src="https://nestjs.com/img/triplecore-logo.svg" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://klqc.de" target="_blank"><img src="https://nestjs.com/img/klcqcl-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://polygon-software.ch/" target="_blank"><img src="https://nestjs.com/img/polygon-logo.svg" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://themobilereality.com/" target="_blank"><img src="https://nestjs.com/img/mobile-reality-logo.png" width="45" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://boringowl.io/" target="_blank"><img src="https://nestjs.com/img/boringowl-logo.svg" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/nordbot-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/dopiosh-logo.png" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.mobilefactory.jp/" target="_blank"><img src="https://nestjs.com/img/mobilefactory-logo.png" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/nordbot-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/dopiosh-logo.png" width="50" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.hingehealth.com/" target="_blank"><img src="https://nestjs.com/img/hinge-health-logo.svg" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://julienferand.dev/" target="_blank"><img src="https://nestjs.com/img/julienferand-logo.jpeg" width="65" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.tripoffice.com/" target="_blank"><img src="https://nestjs.com/img/tripoffice-logo.png" width="140" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://solcellsforetag.se/" target="_blank"><img src="https://nestjs.com/img/solcellsforetag-logo.svg" width="140" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
@@ -127,9 +146,9 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
## Stay in touch
|
||||
|
||||
- Author - [Kamil Myśliwiec](https://x.com/kammysliwiec)
|
||||
- Website - [https://nestjs.com](https://nestjs.com/)
|
||||
- X - [@nestframework](https://x.com/nestframework)
|
||||
* Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||
* Website - [https://nestjs.com](https://nestjs.com/)
|
||||
* Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DiscoveryService } from '@nestjs/core';
|
||||
import { expect } from 'chai';
|
||||
import { AppModule } from '../src/app.module';
|
||||
import { WebhooksExplorer } from '../src/webhooks.explorer';
|
||||
import { NonAppliedDecorator } from '../src/decorators/non-applied.decorator';
|
||||
|
||||
describe('DiscoveryModule', () => {
|
||||
let moduleRef: TestingModule;
|
||||
|
||||
beforeEach(async () => {
|
||||
moduleRef = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
});
|
||||
|
||||
it('should discover all providers & handlers with corresponding annotations', async () => {
|
||||
const webhooksExplorer = moduleRef.get(WebhooksExplorer);
|
||||
|
||||
expect(webhooksExplorer.getWebhooks()).to.be.eql([
|
||||
{
|
||||
handlers: [
|
||||
{
|
||||
event: 'start',
|
||||
methodName: 'onStart',
|
||||
},
|
||||
],
|
||||
name: 'cleanup',
|
||||
},
|
||||
{
|
||||
handlers: [
|
||||
{
|
||||
event: 'start',
|
||||
methodName: 'onStart',
|
||||
},
|
||||
],
|
||||
name: 'flush',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return an empty array if no providers were found for a given discoverable decorator', () => {
|
||||
const discoveryService = moduleRef.get(DiscoveryService);
|
||||
|
||||
const providers = discoveryService.getProviders({
|
||||
metadataKey: NonAppliedDecorator.KEY,
|
||||
});
|
||||
expect(providers).to.be.eql([]);
|
||||
});
|
||||
|
||||
it('should return an empty array if no controllers were found for a given discoverable decorator', () => {
|
||||
const discoveryService = moduleRef.get(DiscoveryService);
|
||||
|
||||
const controllers = discoveryService.getControllers({
|
||||
metadataKey: NonAppliedDecorator.KEY,
|
||||
});
|
||||
expect(controllers).to.be.eql([]);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DiscoveryModule } from '@nestjs/core';
|
||||
import { MyWebhookModule } from './my-webhook/my-webhook.module';
|
||||
import { WebhooksExplorer } from './webhooks.explorer';
|
||||
|
||||
@Module({
|
||||
imports: [MyWebhookModule, DiscoveryModule],
|
||||
providers: [WebhooksExplorer],
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { DiscoveryService } from '@nestjs/core';
|
||||
|
||||
/**
|
||||
* This decorator must not be used anywhere!
|
||||
*
|
||||
* This will be used to test the scenario where we are trying to retrieving
|
||||
* metadata for a discoverable decorator that was not applied to any class.
|
||||
*/
|
||||
export const NonAppliedDecorator = DiscoveryService.createDecorator();
|
||||
@@ -1,6 +0,0 @@
|
||||
import { DiscoveryService } from '@nestjs/core';
|
||||
|
||||
export const Webhook = DiscoveryService.createDecorator<{ name: string }>();
|
||||
export const WebhookHandler = DiscoveryService.createDecorator<{
|
||||
event: string;
|
||||
}>();
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Webhook, WebhookHandler } from '../decorators/webhook.decorators';
|
||||
|
||||
@Webhook({ name: 'cleanup' })
|
||||
export class CleanupWebhook {
|
||||
@WebhookHandler({ event: 'start' })
|
||||
onStart() {
|
||||
console.log('cleanup started');
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Webhook, WebhookHandler } from '../decorators/webhook.decorators';
|
||||
|
||||
@Webhook({ name: 'flush' })
|
||||
export class FlushWebhook {
|
||||
@WebhookHandler({ event: 'start' })
|
||||
onStart() {
|
||||
console.log('flush started');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CleanupWebhook } from './cleanup.webhook';
|
||||
import { FlushWebhook } from './flush.webhook';
|
||||
|
||||
@Module({ providers: [CleanupWebhook, FlushWebhook] })
|
||||
export class MyWebhookModule {}
|
||||
@@ -1,39 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DiscoveryService, MetadataScanner } from '@nestjs/core';
|
||||
import { Webhook, WebhookHandler } from './decorators/webhook.decorators';
|
||||
|
||||
@Injectable()
|
||||
export class WebhooksExplorer {
|
||||
constructor(
|
||||
private readonly discoveryService: DiscoveryService,
|
||||
private readonly metadataScanner: MetadataScanner,
|
||||
) {}
|
||||
|
||||
getWebhooks() {
|
||||
const webhooks = this.discoveryService.getProviders({
|
||||
metadataKey: Webhook.KEY,
|
||||
});
|
||||
return webhooks.map(wrapper => {
|
||||
const { name } = this.discoveryService.getMetadataByDecorator(
|
||||
Webhook,
|
||||
wrapper,
|
||||
);
|
||||
return {
|
||||
name,
|
||||
handlers: this.metadataScanner
|
||||
.getAllMethodNames(wrapper.metatype.prototype)
|
||||
.map(methodName => {
|
||||
const { event } = this.discoveryService.getMetadataByDecorator(
|
||||
WebhookHandler,
|
||||
wrapper,
|
||||
methodName,
|
||||
);
|
||||
return {
|
||||
methodName,
|
||||
event,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "ES2021",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist",
|
||||
"paths": {
|
||||
"@nestjs/common": ["../../packages/common"],
|
||||
"@nestjs/common/*": ["../../packages/common/*"],
|
||||
"@nestjs/core": ["../../packages/core"],
|
||||
"@nestjs/core/*": ["../../packages/core/*"],
|
||||
"@nestjs/microservices": ["../../packages/microservices"],
|
||||
"@nestjs/microservices/*": ["../../packages/microservices/*"],
|
||||
"@nestjs/websockets": ["../../packages/websockets"],
|
||||
"@nestjs/websockets/*": ["../../packages/websockets/*"],
|
||||
"@nestjs/testing": ["../../packages/testing"],
|
||||
"@nestjs/testing/*": ["../../packages/testing/*"],
|
||||
"@nestjs/platform-express": ["../../packages/platform-express"],
|
||||
"@nestjs/platform-express/*": ["../../packages/platform-express/*"],
|
||||
"@nestjs/platform-socket.io": ["../../packages/platform-socket.io"],
|
||||
"@nestjs/platform-socket.io/*": ["../../packages/platform-socket.io/*"],
|
||||
"@nestjs/platform-ws": ["../../packages/platform-ws"],
|
||||
"@nestjs/platform-ws/*": ["../../packages/platform-ws/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
@@ -25,7 +25,7 @@ services:
|
||||
- "9001:9001"
|
||||
restart: always
|
||||
mysql:
|
||||
image: mysql:8.3.0
|
||||
image: mysql:8.0.32
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: test
|
||||
@@ -50,7 +50,7 @@ services:
|
||||
zookeeper:
|
||||
container_name: test-zookeeper
|
||||
hostname: zookeeper
|
||||
image: confluentinc/cp-zookeeper:7.5.3
|
||||
image: confluentinc/cp-zookeeper:7.3.2
|
||||
ports:
|
||||
- "2181:2181"
|
||||
environment:
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
kafka:
|
||||
container_name: test-kafka
|
||||
hostname: kafka
|
||||
image: confluentinc/cp-kafka:7.5.3
|
||||
image: confluentinc/cp-kafka:7.3.2
|
||||
depends_on:
|
||||
- zookeeper
|
||||
ports:
|
||||
|
||||
@@ -192,7 +192,7 @@ describe('Middleware (FastifyAdapter)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('should execute middleware only once for given routes', () => {
|
||||
describe.only('should execute middleware only once for given routes', () => {
|
||||
class Middleware implements NestMiddleware {
|
||||
use(request: any, reply: any, next: () => void) {
|
||||
if (request.middlewareExecutionCount === undefined) {
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { Controller, Injectable, Module } from '@nestjs/common';
|
||||
|
||||
class B {}
|
||||
|
||||
@Injectable()
|
||||
class A {
|
||||
constructor(b: B) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class BImpl {
|
||||
constructor(a: A) {}
|
||||
}
|
||||
|
||||
@Controller()
|
||||
class AppController {
|
||||
constructor(a: A) {}
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [AppController],
|
||||
providers: [A, { provide: B, useClass: BImpl }],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
describe('Circular custom providers', () => {
|
||||
it('should throw an exception (useClass + regular provider)', async () => {
|
||||
try {
|
||||
const builder = Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
});
|
||||
await builder.compile();
|
||||
|
||||
expect(true).to.be.eql(false);
|
||||
} catch (err) {
|
||||
expect(err.message).to.be.eql(
|
||||
'A circular dependency has been detected inside "A". Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()". Note that circular relationships between custom providers (e.g., factories) are not supported since functions cannot be called more than once.',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an exception (2 factories)', async () => {
|
||||
try {
|
||||
const builder = Test.createTestingModule({
|
||||
providers: [
|
||||
{ provide: 'ABC', useFactory: () => ({}), inject: ['DEF'] },
|
||||
{ provide: 'DEF', useFactory: () => ({}), inject: ['ABC'] },
|
||||
],
|
||||
});
|
||||
await builder.compile();
|
||||
|
||||
expect(true).to.be.eql(false);
|
||||
} catch (err) {
|
||||
expect(err.message).to.be.eql(
|
||||
'A circular dependency has been detected inside "ABC". Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()". Note that circular relationships between custom providers (e.g., factories) are not supported since functions cannot be called more than once.',
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -118,14 +118,14 @@ describe('Optional factory provider deps', () => {
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceOf(UnknownDependenciesException);
|
||||
expect(err.message).to
|
||||
.equal(`Nest can't resolve dependencies of the POSSIBLY_MISSING_DEP (?). Please make sure that the argument "MISSING_DEP" at index [0] is available in the RootTestModule context.
|
||||
.equal(`Nest can't resolve dependencies of the POSSIBLY_MISSING_DEP (?). Please make sure that the argument MISSING_DEP at index [0] is available in the RootTestModule context.
|
||||
|
||||
Potential solutions:
|
||||
- Is RootTestModule a valid NestJS module?
|
||||
- If "MISSING_DEP" is a provider, is it part of the current RootTestModule?
|
||||
- If "MISSING_DEP" is exported from a separate @Module, is that module imported within RootTestModule?
|
||||
- If MISSING_DEP is a provider, is it part of the current RootTestModule?
|
||||
- If MISSING_DEP is exported from a separate @Module, is that module imported within RootTestModule?
|
||||
@Module({
|
||||
imports: [ /* the Module containing "MISSING_DEP" */ ]
|
||||
imports: [ /* the Module containing MISSING_DEP */ ]
|
||||
})
|
||||
`);
|
||||
}
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "ExternalContextCreator",
|
||||
"initTime": 0
|
||||
"token": "ExternalContextCreator"
|
||||
}
|
||||
},
|
||||
"208171089": {
|
||||
@@ -800,10 +800,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "ModulesContainer",
|
||||
"initTime": 0
|
||||
"token": "ModulesContainer"
|
||||
}
|
||||
},
|
||||
"-326832201": {
|
||||
@@ -816,10 +816,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "HttpAdapterHost",
|
||||
"initTime": 0
|
||||
"token": "HttpAdapterHost"
|
||||
}
|
||||
},
|
||||
"-702581189": {
|
||||
@@ -848,10 +848,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "SerializedGraph",
|
||||
"initTime": 0
|
||||
"token": "SerializedGraph"
|
||||
}
|
||||
},
|
||||
"-1251270035": {
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "ExternalContextCreator",
|
||||
"initTime": 0
|
||||
"token": "ExternalContextCreator"
|
||||
}
|
||||
},
|
||||
"208171089": {
|
||||
@@ -784,10 +784,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "ModulesContainer",
|
||||
"initTime": 0
|
||||
"token": "ModulesContainer"
|
||||
}
|
||||
},
|
||||
"-326832201": {
|
||||
@@ -800,10 +800,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "HttpAdapterHost",
|
||||
"initTime": 0
|
||||
"token": "HttpAdapterHost"
|
||||
}
|
||||
},
|
||||
"-702581189": {
|
||||
@@ -832,10 +832,10 @@
|
||||
"sourceModuleName": "InternalCoreModule",
|
||||
"durable": false,
|
||||
"static": true,
|
||||
"scope": 0,
|
||||
"transient": false,
|
||||
"exported": true,
|
||||
"token": "SerializedGraph",
|
||||
"initTime": 0
|
||||
"token": "SerializedGraph"
|
||||
}
|
||||
},
|
||||
"-1251270035": {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import * as chai from 'chai';
|
||||
import { expect } from 'chai';
|
||||
import chaiAsPromised = require('chai-as-promised');
|
||||
import { AppModule } from '../src/app.module';
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
describe('Lazy imports', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication();
|
||||
server = app.getHttpAdapter().getInstance();
|
||||
});
|
||||
|
||||
it(`should allow imports of global modules`, async () => {
|
||||
await expect(app.init()).to.eventually.be.fulfilled;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LazyModuleLoader } from '@nestjs/core';
|
||||
import { EagerModule } from './eager.module';
|
||||
import { GlobalModule } from './global.module';
|
||||
import { LazyModule } from './lazy.module';
|
||||
|
||||
@Module({
|
||||
imports: [GlobalModule, EagerModule],
|
||||
})
|
||||
export class AppModule {
|
||||
constructor(public loader: LazyModuleLoader) {}
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
await this.loader.load(() => LazyModule);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Module, Injectable } from '@nestjs/common';
|
||||
import { GlobalService } from './global.module';
|
||||
|
||||
@Injectable()
|
||||
export class EagerService {
|
||||
constructor(public globalService: GlobalService) {}
|
||||
}
|
||||
|
||||
@Module({
|
||||
providers: [EagerService],
|
||||
})
|
||||
export class EagerModule {}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Module, Injectable, Global } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class GlobalService {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [GlobalService],
|
||||
exports: [GlobalService],
|
||||
})
|
||||
export class GlobalModule {}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Module, Injectable } from '@nestjs/common';
|
||||
import { GlobalService } from './global.module';
|
||||
|
||||
@Injectable()
|
||||
export class LazyService {
|
||||
constructor(public globalService: GlobalService) {}
|
||||
}
|
||||
|
||||
@Module({
|
||||
providers: [LazyService],
|
||||
})
|
||||
export class LazyModule {}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
await app.listen(3000);
|
||||
}
|
||||
bootstrap();
|
||||
@@ -128,27 +128,6 @@ describe('GRPC transport', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(`GRPC with backpressure control`, async function () {
|
||||
// This test hit the gRPC server with 1000 messages, but the server
|
||||
// has to process large (> 1MB) messages, so it will definitely hit
|
||||
// issues where writing to the stream needs to be paused until a drain
|
||||
// event. Prior to this test, a bug existed where the server would
|
||||
// send the incorrect number of messages due to improper backpressure
|
||||
// handling that wrote messages more than once.
|
||||
this.timeout(10000);
|
||||
|
||||
const largeMessages = client.streamLargeMessages();
|
||||
// [0, 1, 2, ..., 999]
|
||||
const expectedIds = Array.from({ length: 1000 }, (_, n) => n);
|
||||
const receivedIds: number[] = [];
|
||||
|
||||
await largeMessages.forEach(msg => {
|
||||
receivedIds.push(msg.id);
|
||||
});
|
||||
|
||||
expect(receivedIds).to.deep.equal(expectedIds);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -128,27 +128,6 @@ export class GrpcController {
|
||||
return svc.sum2({ data });
|
||||
}
|
||||
|
||||
@GrpcMethod('Math')
|
||||
streamLargeMessages(_req: unknown, _meta: unknown) {
|
||||
// Send 1000 messages of >1MB each relatively fast
|
||||
// This should be enough to trigger backpressure issues
|
||||
// while writing to the socket.
|
||||
return new Observable(subscriber => {
|
||||
let n = 0;
|
||||
const interval = setInterval(() => {
|
||||
// We'll be checking the ids. The `data` is just to make the
|
||||
// message large enough to trigger backpressure issues.
|
||||
subscriber.next({ id: n++, data: 'a'.repeat(1024 * 1024) });
|
||||
if (n === 1000) {
|
||||
subscriber.complete();
|
||||
}
|
||||
}, 0);
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@Post('error')
|
||||
@HttpCode(200)
|
||||
serializeError(
|
||||
|
||||
@@ -7,16 +7,8 @@ service Math {
|
||||
rpc SumStream(stream RequestSum) returns(stream SumResult);
|
||||
rpc SumStreamPass(stream RequestSum) returns(stream SumResult);
|
||||
rpc Divide (RequestDivide) returns (DivideResult);
|
||||
rpc StreamLargeMessages(Empty) returns (stream BackpressureData) {}
|
||||
}
|
||||
|
||||
message BackpressureData {
|
||||
int32 id = 1;
|
||||
string data = 2;
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
message SumResult {
|
||||
int32 result = 1;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import { CatsModule } from './cats/cats.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MongooseModule.forRoot('mongodb://localhost:27017/test'),
|
||||
MongooseModule.forRoot('mongodb://localhost:27017/test', {
|
||||
useNewUrlParser: true,
|
||||
}),
|
||||
CatsModule,
|
||||
],
|
||||
})
|
||||
|
||||
@@ -10,6 +10,7 @@ class ConfigService implements MongooseOptionsFactory {
|
||||
createMongooseOptions(): MongooseModuleOptions {
|
||||
return {
|
||||
uri: 'mongodb://localhost:27017/test',
|
||||
useNewUrlParser: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class ConfigService implements MongooseOptionsFactory {
|
||||
createMongooseOptions(): MongooseModuleOptions {
|
||||
return {
|
||||
uri: 'mongodb://localhost:27017/test',
|
||||
useNewUrlParser: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { CatsModule } from './cats/cats.module';
|
||||
imports: [
|
||||
MongooseModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
useNewUrlParser: true,
|
||||
uri: 'mongodb://localhost:27017/test',
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -130,18 +130,6 @@ describe('Global prefix', () => {
|
||||
.expect(200, { '0': 'params', tenantId: 'test' });
|
||||
});
|
||||
|
||||
it(`should execute middleware only once`, async () => {
|
||||
app.setGlobalPrefix('/api', { exclude: ['/'] });
|
||||
|
||||
server = app.getHttpServer();
|
||||
await app.init();
|
||||
|
||||
await request(server)
|
||||
.get('/')
|
||||
.expect(200, 'Extras: Data attached in middleware, Count: 1');
|
||||
await request(server).get('/api/count').expect(200, '2');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -26,14 +26,4 @@ export class AppController {
|
||||
postTest(): string {
|
||||
return 'test';
|
||||
}
|
||||
|
||||
@Get()
|
||||
getHome(@Req() req) {
|
||||
return 'Extras: ' + req.extras?.data + ', Count: ' + req.count;
|
||||
}
|
||||
|
||||
@Get('count')
|
||||
getCount(@Req() req) {
|
||||
return req.count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ export const MIDDLEWARE_PARAM_VALUE = 'middleware_param';
|
||||
controllers: [AppController],
|
||||
})
|
||||
export class AppModule {
|
||||
private count = 0;
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply((req, res, next) => res.end(MIDDLEWARE_VALUE))
|
||||
@@ -28,12 +27,6 @@ export class AppModule {
|
||||
req.middlewareParams = req.params;
|
||||
next();
|
||||
})
|
||||
.forRoutes({ path: '*', method: RequestMethod.GET })
|
||||
.apply((req, res, next) => {
|
||||
this.count += 1;
|
||||
req.count = this.count;
|
||||
next();
|
||||
})
|
||||
.forRoutes('*');
|
||||
.forRoutes({ path: '*', method: RequestMethod.GET });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export class AppController {
|
||||
@Sse('sse')
|
||||
sse(): Observable<MessageEvent> {
|
||||
return interval(1000).pipe(
|
||||
map(_ => ({ data: { hello: 'world' } }) as MessageEvent),
|
||||
map(_ => ({ data: { hello: 'world' } } as MessageEvent)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('Fastify FileSend', () => {
|
||||
expect(headers['content-disposition']).to.equal(
|
||||
'attachment; filename="Readme.md"',
|
||||
);
|
||||
expect(headers['content-length']).to.equal(`${readme.byteLength}`);
|
||||
expect(headers['content-length']).to.equal(readme.byteLength);
|
||||
expect(payload).to.equal(readmeString);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "mysql",
|
||||
"host": "127.0.0.1",
|
||||
"host": "localhost",
|
||||
"port": 3306,
|
||||
"username": "root",
|
||||
"password": "root",
|
||||
|
||||
@@ -7,7 +7,7 @@ import { PhotoModule } from './photo/photo.module';
|
||||
imports: [
|
||||
TypeOrmModule.forRoot({
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
|
||||
@@ -11,7 +11,7 @@ class ConfigService implements TypeOrmOptionsFactory {
|
||||
createTypeOrmOptions(): TypeOrmModuleOptions {
|
||||
return {
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
|
||||
@@ -11,7 +11,7 @@ class ConfigService implements TypeOrmOptionsFactory {
|
||||
createTypeOrmOptions(): TypeOrmModuleOptions {
|
||||
return {
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
|
||||
@@ -8,7 +8,7 @@ import { PhotoModule } from './photo/photo.module';
|
||||
TypeOrmModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
|
||||
@@ -11,7 +11,7 @@ export class DatabaseModule {
|
||||
imports: [
|
||||
TypeOrmModule.forRoot({
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
|
||||
@@ -418,67 +418,4 @@ describe('URI Versioning', () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
|
||||
// ======================================================================== //
|
||||
describe('with middleware applied', () => {
|
||||
before(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
app.enableVersioning({
|
||||
type: VersioningType.URI,
|
||||
defaultVersion: '1',
|
||||
});
|
||||
await app.init();
|
||||
});
|
||||
|
||||
describe('GET /middleware', () => {
|
||||
it('should return "Hello from middleware function!"', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/v1/middleware')
|
||||
.expect(200)
|
||||
.expect('Hello from middleware function!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /middleware/override', () => {
|
||||
it('should return "Hello from middleware function!"', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/v2/middleware/override')
|
||||
.expect(200)
|
||||
.expect('Hello from middleware function!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /middleware/multiple', () => {
|
||||
it('should return "Hello from middleware function!" (v1)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/v1/middleware/multiple')
|
||||
.expect(200)
|
||||
.expect('Hello from middleware function!');
|
||||
});
|
||||
|
||||
it('should return "Hello from middleware function!" (v2)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/v2/middleware/multiple')
|
||||
.expect(200)
|
||||
.expect('Hello from middleware function!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /middleware/neutral', () => {
|
||||
it('should return "Hello from middleware function!"', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/middleware/neutral')
|
||||
.expect(200)
|
||||
.expect('Hello from middleware function!');
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { MiddlewareConsumer, Module } from '@nestjs/common';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppV1Controller } from './app-v1.controller';
|
||||
import { AppV2Controller } from './app-v2.controller';
|
||||
import { MiddlewareController } from './middleware.controller';
|
||||
import { MultipleMiddlewareVersionController } from './multiple-middleware.controller';
|
||||
import { MultipleVersionController } from './multiple.controller';
|
||||
import { VersionNeutralMiddlewareController } from './neutral-middleware.controller';
|
||||
import { VersionNeutralController } from './neutral.controller';
|
||||
import { NoVersioningController } from './no-versioning.controller';
|
||||
import { OverridePartialController } from './override-partial.controller';
|
||||
import { VersionNeutralController } from './neutral.controller';
|
||||
import { OverrideController } from './override.controller';
|
||||
import { OverridePartialController } from './override-partial.controller';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
@@ -20,19 +17,6 @@ import { OverrideController } from './override.controller';
|
||||
VersionNeutralController,
|
||||
OverrideController,
|
||||
OverridePartialController,
|
||||
MiddlewareController,
|
||||
MultipleMiddlewareVersionController,
|
||||
VersionNeutralMiddlewareController,
|
||||
],
|
||||
})
|
||||
export class AppModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply((req, res) => res.end('Hello from middleware function!'))
|
||||
.forRoutes(
|
||||
MiddlewareController,
|
||||
MultipleMiddlewareVersionController,
|
||||
VersionNeutralMiddlewareController,
|
||||
);
|
||||
}
|
||||
}
|
||||
export class AppModule {}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Controller, Get, Version } from '@nestjs/common';
|
||||
|
||||
@Controller({
|
||||
path: 'middleware',
|
||||
version: '1',
|
||||
})
|
||||
export class MiddlewareController {
|
||||
@Get('/')
|
||||
hello() {
|
||||
return 'Hello from "MiddlewareController"!';
|
||||
}
|
||||
|
||||
@Version('2')
|
||||
@Get('/override')
|
||||
hellov2() {
|
||||
return 'Hello from "MiddlewareController"!';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
|
||||
@Controller({
|
||||
version: ['1', '2'],
|
||||
path: 'middleware',
|
||||
})
|
||||
export class MultipleMiddlewareVersionController {
|
||||
@Get('/multiple')
|
||||
multiple() {
|
||||
return 'Multiple Versions 1 or 2';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';
|
||||
|
||||
@Controller({
|
||||
path: 'middleware',
|
||||
version: VERSION_NEUTRAL,
|
||||
})
|
||||
export class VersionNeutralMiddlewareController {
|
||||
@Get('/neutral')
|
||||
neutral() {
|
||||
return 'Neutral';
|
||||
}
|
||||
}
|
||||
@@ -66,37 +66,5 @@ describe('WebSocketGateway', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it(`should be able to get the pattern in an interceptor`, async () => {
|
||||
app = await createNestApp(ApplicationGateway);
|
||||
await app.listen(3000);
|
||||
|
||||
ws = io('http://localhost:8080');
|
||||
ws.emit('getClient', {
|
||||
test: 'test',
|
||||
});
|
||||
await new Promise<void>(resolve =>
|
||||
ws.on('popClient', data => {
|
||||
expect(data.path).to.be.eql('getClient');
|
||||
resolve();
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it(`should be able to get the pattern in a filter (when the error comes from a known handler)`, async () => {
|
||||
app = await createNestApp(ApplicationGateway);
|
||||
await app.listen(3000);
|
||||
|
||||
ws = io('http://localhost:8080');
|
||||
ws.emit('getClientWithError', {
|
||||
test: 'test',
|
||||
});
|
||||
await new Promise<void>(resolve =>
|
||||
ws.on('exception', data => {
|
||||
expect(data.pattern).to.be.eql('getClientWithError');
|
||||
resolve();
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => app.close());
|
||||
});
|
||||
|
||||
@@ -194,30 +194,6 @@ describe('WebSocketGateway (WsAdapter)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should let the execution context have a getPattern() method on getClient()', async () => {
|
||||
app = await createNestApp(ApplicationGateway);
|
||||
await app.listen(3000);
|
||||
|
||||
ws = new WebSocket('ws://localhost:8080');
|
||||
await new Promise(resolve => ws.on('open', resolve));
|
||||
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: 'getClient',
|
||||
data: {
|
||||
test: 'test',
|
||||
},
|
||||
}),
|
||||
);
|
||||
await new Promise<void>(resolve =>
|
||||
ws.on('message', data => {
|
||||
expect(JSON.parse(data).data.path).to.be.eql('getClient');
|
||||
ws.close();
|
||||
resolve();
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { UseFilters, UseInterceptors } from '@nestjs/common';
|
||||
import {
|
||||
MessageBody,
|
||||
SubscribeMessage,
|
||||
WebSocketGateway,
|
||||
WsException,
|
||||
} from '@nestjs/websockets';
|
||||
import { RequestInterceptor } from './request.interceptor';
|
||||
import { throwError } from 'rxjs';
|
||||
import { RequestFilter } from './request.filter';
|
||||
|
||||
@WebSocketGateway(8080)
|
||||
export class ApplicationGateway {
|
||||
@@ -18,19 +13,4 @@ export class ApplicationGateway {
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
@UseInterceptors(RequestInterceptor)
|
||||
@SubscribeMessage('getClient')
|
||||
getPathCalled(client, data) {
|
||||
return {
|
||||
event: 'popClient',
|
||||
data: { ...data, path: client.pattern },
|
||||
};
|
||||
}
|
||||
|
||||
@UseFilters(RequestFilter)
|
||||
@SubscribeMessage('getClientWithError')
|
||||
getPathCalledWithError() {
|
||||
return throwError(() => new WsException('This is an error'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';
|
||||
import { WsException } from '@nestjs/websockets';
|
||||
|
||||
@Catch(WsException)
|
||||
export class RequestFilter implements ExceptionFilter {
|
||||
catch(exception: WsException, host: ArgumentsHost) {
|
||||
const wsCtx = host.switchToWs();
|
||||
const pattern = wsCtx.getPattern();
|
||||
const client = wsCtx.getClient();
|
||||
client.emit('exception', { pattern, message: exception.message });
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { CallHandler, ExecutionContext, Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class RequestInterceptor {
|
||||
intercept(context: ExecutionContext, next: CallHandler) {
|
||||
const client = context.switchToWs().getClient();
|
||||
const pattern = context.switchToWs().getPattern();
|
||||
client.pattern = pattern;
|
||||
return next.handle();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import { UseInterceptors } from '@nestjs/common';
|
||||
import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets';
|
||||
import { RequestInterceptor } from './request.interceptor';
|
||||
|
||||
@WebSocketGateway()
|
||||
export class ServerGateway {
|
||||
@@ -11,13 +9,4 @@ export class ServerGateway {
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
@UseInterceptors(RequestInterceptor)
|
||||
@SubscribeMessage('getClient')
|
||||
getPathCalled(client, data) {
|
||||
return {
|
||||
event: 'popClient',
|
||||
data: { ...data, path: client.pattern },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "10.3.5"
|
||||
"version": "9.4.2"
|
||||
}
|
||||
|
||||
53204
package-lock.json
generated
53204
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
150
package.json
150
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/core",
|
||||
"version": "10.3.4",
|
||||
"version": "9.4.0",
|
||||
"description": "Modern, fast, powerful node.js web framework",
|
||||
"homepage": "https://nestjs.com",
|
||||
"repository": {
|
||||
@@ -25,14 +25,14 @@
|
||||
"move:node_modules": "gulp move:node_modules",
|
||||
"build:samples": "gulp install:samples && npm run build && npm run move:samples && gulp build:samples && gulp test:samples && gulp test:e2e:samples",
|
||||
"codechecks:benchmarks": "codechecks ./tools/benchmarks/check-benchmarks.ts",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls -v",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||
"format": "prettier \"**/*.ts\" \"packages/**/*.json\" --ignore-path ./.prettierignore --write && git status",
|
||||
"postinstall": "opencollective",
|
||||
"test": "mocha packages/**/*.spec.ts",
|
||||
"test:dev": "mocha -w --watch-files \"packages\" packages/**/*.spec.ts",
|
||||
"pretest:cov": "npm run clean",
|
||||
"test:cov": "nyc mocha packages/**/*.spec.ts --reporter spec",
|
||||
"test:integration": "mocha --reporter-option maxDiffSize=0 \"integration/*/{,!(node_modules)/**/}/*.spec.ts\"",
|
||||
"test:integration": "mocha \"integration/*/{,!(node_modules)/**/}/*.spec.ts\"",
|
||||
"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'",
|
||||
@@ -47,7 +47,7 @@
|
||||
"publish:next": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --npm-tag=next --access public --skip-git -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:rc": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --npm-tag=rc --access public -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:test": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --force-publish --access public --npm-tag=test --skip-git -m \"chore(@nestjs) publish %s release\"",
|
||||
"prepare": "husky"
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.ts": [
|
||||
@@ -60,80 +60,80 @@
|
||||
"dependencies": {
|
||||
"@nuxtjs/opencollective": "0.3.2",
|
||||
"class-transformer": "0.5.1",
|
||||
"class-validator": "0.14.1",
|
||||
"cli-color": "2.0.4",
|
||||
"class-validator": "0.14.0",
|
||||
"cli-color": "2.0.3",
|
||||
"cors": "2.8.5",
|
||||
"express": "4.18.3",
|
||||
"fast-json-stringify": "5.13.0",
|
||||
"express": "4.18.2",
|
||||
"fast-json-stringify": "5.7.0",
|
||||
"fast-safe-stringify": "2.1.1",
|
||||
"graphql-subscriptions": "2.0.0",
|
||||
"iterare": "1.2.1",
|
||||
"object-hash": "3.0.0",
|
||||
"path-to-regexp": "3.2.0",
|
||||
"reflect-metadata": "0.2.1",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rxjs": "7.8.1",
|
||||
"socket.io": "4.7.5",
|
||||
"tslib": "2.6.2",
|
||||
"socket.io": "4.6.1",
|
||||
"tslib": "2.5.2",
|
||||
"uid": "2.0.2",
|
||||
"uuid": "9.0.1"
|
||||
"uuid": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apollo/server": "4.10.1",
|
||||
"@apollo/server": "4.7.1",
|
||||
"@codechecks/client": "0.1.12",
|
||||
"@commitlint/cli": "19.2.0",
|
||||
"@commitlint/config-angular": "19.1.0",
|
||||
"@fastify/cors": "9.0.1",
|
||||
"@commitlint/cli": "17.6.3",
|
||||
"@commitlint/config-angular": "17.6.3",
|
||||
"@fastify/cors": "8.2.1",
|
||||
"@fastify/formbody": "7.4.0",
|
||||
"@fastify/middie": "8.3.0",
|
||||
"@fastify/multipart": "8.1.0",
|
||||
"@fastify/static": "7.0.1",
|
||||
"@fastify/view": "9.0.0",
|
||||
"@grpc/grpc-js": "1.10.3",
|
||||
"@grpc/proto-loader": "0.7.10",
|
||||
"@nestjs/apollo": "12.1.0",
|
||||
"@nestjs/graphql": "12.1.1",
|
||||
"@nestjs/mongoose": "10.0.4",
|
||||
"@nestjs/typeorm": "10.0.2",
|
||||
"@types/amqplib": "0.10.5",
|
||||
"@types/bytes": "3.1.4",
|
||||
"@types/chai": "4.3.11",
|
||||
"@types/chai-as-promised": "7.1.8",
|
||||
"@types/cors": "2.8.17",
|
||||
"@types/express": "4.17.21",
|
||||
"@types/gulp": "4.0.17",
|
||||
"@types/http-errors": "2.0.4",
|
||||
"@types/mocha": "10.0.6",
|
||||
"@types/node": "20.11.29",
|
||||
"@types/sinon": "17.0.3",
|
||||
"@types/supertest": "2.0.16",
|
||||
"@types/ws": "8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "7.3.1",
|
||||
"@typescript-eslint/parser": "7.3.1",
|
||||
"amqp-connection-manager": "4.1.14",
|
||||
"@fastify/multipart": "7.6.0",
|
||||
"@fastify/static": "6.10.1",
|
||||
"@fastify/view": "7.4.1",
|
||||
"@grpc/grpc-js": "1.8.14",
|
||||
"@grpc/proto-loader": "0.7.7",
|
||||
"@nestjs/apollo": "11.0.5",
|
||||
"@nestjs/graphql": "11.0.5",
|
||||
"@nestjs/mongoose": "9.2.2",
|
||||
"@nestjs/typeorm": "9.0.1",
|
||||
"@types/amqplib": "0.10.1",
|
||||
"@types/bytes": "3.1.1",
|
||||
"@types/chai": "4.3.5",
|
||||
"@types/chai-as-promised": "7.1.5",
|
||||
"@types/cors": "2.8.13",
|
||||
"@types/express": "4.17.17",
|
||||
"@types/gulp": "4.0.10",
|
||||
"@types/http-errors": "2.0.1",
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/node": "20.2.3",
|
||||
"@types/sinon": "10.0.15",
|
||||
"@types/supertest": "2.0.12",
|
||||
"@types/ws": "8.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||
"@typescript-eslint/parser": "4.33.0",
|
||||
"amqp-connection-manager": "4.1.13",
|
||||
"amqplib": "0.10.3",
|
||||
"artillery": "2.0.8",
|
||||
"artillery": "1.7.9",
|
||||
"body-parser": "1.20.2",
|
||||
"bytes": "3.1.2",
|
||||
"cache-manager": "5.4.0",
|
||||
"cache-manager": "5.2.1",
|
||||
"cache-manager-redis-store": "3.0.1",
|
||||
"chai": "4.4.1",
|
||||
"chai": "4.3.7",
|
||||
"chai-as-promised": "7.1.1",
|
||||
"clang-format": "1.8.0",
|
||||
"commitlint-circle": "1.0.0",
|
||||
"concurrently": "8.2.2",
|
||||
"conventional-changelog": "5.1.0",
|
||||
"core-js": "3.36.0",
|
||||
"concurrently": "8.0.1",
|
||||
"conventional-changelog": "3.1.25",
|
||||
"core-js": "3.30.2",
|
||||
"coveralls": "3.1.1",
|
||||
"delete-empty": "3.0.0",
|
||||
"engine.io-client": "6.5.3",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"engine.io-client": "6.4.0",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eventsource": "2.0.2",
|
||||
"fancy-log": "2.0.0",
|
||||
"fastify": "4.26.2",
|
||||
"graphql": "16.8.1",
|
||||
"graphql-tools": "9.0.1",
|
||||
"fastify": "4.17.0",
|
||||
"graphql": "16.6.0",
|
||||
"graphql-tools": "9.0.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-clang-format": "1.0.27",
|
||||
"gulp-clean": "0.4.0",
|
||||
@@ -141,42 +141,42 @@
|
||||
"gulp-typescript": "5.0.1",
|
||||
"gulp-watch": "5.0.1",
|
||||
"http-errors": "2.0.0",
|
||||
"husky": "9.0.11",
|
||||
"imports-loader": "5.0.0",
|
||||
"husky": "8.0.3",
|
||||
"imports-loader": "4.0.1",
|
||||
"ioredis": "5.3.2",
|
||||
"json-loader": "0.5.7",
|
||||
"kafkajs": "2.2.4",
|
||||
"lerna": "2.11.0",
|
||||
"lerna-changelog": "2.2.0",
|
||||
"light-my-request": "5.12.0",
|
||||
"lint-staged": "15.2.2",
|
||||
"light-my-request": "5.9.1",
|
||||
"lint-staged": "13.2.2",
|
||||
"markdown-table": "2.0.0",
|
||||
"merge-graphql-schemas": "1.7.8",
|
||||
"mocha": "10.3.0",
|
||||
"mongoose": "8.2.2",
|
||||
"mqtt": "5.5.0",
|
||||
"mocha": "10.2.0",
|
||||
"mongoose": "7.2.0",
|
||||
"mqtt": "4.3.7",
|
||||
"multer": "1.4.4",
|
||||
"mysql2": "3.9.2",
|
||||
"nats": "2.19.0",
|
||||
"nodemon": "3.1.0",
|
||||
"nyc": "14.1.1",
|
||||
"prettier": "3.2.5",
|
||||
"redis": "4.6.13",
|
||||
"mysql2": "3.3.1",
|
||||
"nats": "2.13.1",
|
||||
"nodemon": "2.0.22",
|
||||
"nyc": "15.1.0",
|
||||
"prettier": "2.8.8",
|
||||
"redis": "4.6.6",
|
||||
"rxjs-compat": "6.6.7",
|
||||
"sinon": "17.0.1",
|
||||
"sinon": "15.1.0",
|
||||
"sinon-chai": "3.7.0",
|
||||
"socket.io-client": "4.7.5",
|
||||
"socket.io-client": "4.6.1",
|
||||
"subscriptions-transport-ws": "0.11.0",
|
||||
"supertest": "6.3.3",
|
||||
"ts-morph": "22.0.0",
|
||||
"ts-node": "10.9.2",
|
||||
"typeorm": "0.3.20",
|
||||
"typescript": "5.4.2",
|
||||
"ts-morph": "18.0.0",
|
||||
"ts-node": "10.9.1",
|
||||
"typeorm": "0.3.16",
|
||||
"typescript": "5.0.4",
|
||||
"wrk": "1.2.1",
|
||||
"ws": "8.16.0"
|
||||
"ws": "8.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
"node": ">= 12.9.0"
|
||||
},
|
||||
"collective": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
|
||||
## Description
|
||||
|
||||
Nest is a framework for building efficient, scalable <a href="https://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="https://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
|
||||
Nest is a framework for building efficient, scalable <a href="http://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="http://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
|
||||
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also provides compatibility with a wide range of other libraries, like <a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>, allowing for easy use of the myriad of third-party plugins which are available.</p>
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also, provides compatibility with a wide range of other libraries, like e.g. <a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>, allowing for easy use of the myriad third-party plugins which are available.</p>
|
||||
|
||||
## Philosophy
|
||||
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a>, and <a href="https://github.com/vuejs/vue" target="_blank">Vue</a>, which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers, and tools for Node, none of them effectively solve the main problem - the architecture.</p>
|
||||
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, and loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a> and <a href="https://github.com/vuejs/vue" target="_blank">Vue</a> which improve developer productivity and enable the construction of fast, testable, extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers and tools for Node, none of them effectively solve the main problem - the architecture.</p>
|
||||
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>
|
||||
|
||||
## Getting started
|
||||
|
||||
- To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
- 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
- [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
|
||||
- [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
|
||||
* To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
* 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
* [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
|
||||
* [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
|
||||
|
||||
## Questions
|
||||
|
||||
@@ -56,44 +56,45 @@ With official support, you can get expert help straight from Nest core team. We
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support from the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
||||
#### Principal Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" 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="170" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/red-hat-logo.svg" width="200" valign="middle" /></a></td>
|
||||
<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://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" valign="middle" /></a></td>
|
||||
<td>
|
||||
<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><td>
|
||||
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://weld.app/" target="_blank"><img src="https://nestjs.com/img/weld-logo.svg" width="140" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td></tr><tr>
|
||||
<a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="90" valign="middle" /></a></td><td>
|
||||
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="110" valign="middle" /></a></td><td>
|
||||
<a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/snyk-logo-black.png" width="185" valign="middle" /></a></td><td>
|
||||
<a href="https://fuseautotech.com/" target="_blank"><img src="https://nestjs.com/img/fuse-logo.svg" width="105" valign="middle" /></a></td>
|
||||
<td>
|
||||
<a href="https://ridicorp.com/career/" target="_blank"><img src="https://nestjs.com/img/ridi-logo.svg" width="105" valign="middle" /></a></td><td>
|
||||
<a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://nestjs.com/img/movavi-logo.svg" width="105" valign="middle" /></a></td>
|
||||
</tr><tr><td>
|
||||
<a href="https://skunk.team" target="_blank"><img src="https://nestjs.com/img/skunk-logo.png" height="60" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
<a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://nestjs.com/img/movavi-logo.svg" width="105" valign="middle" /></a></td></</tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr>
|
||||
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td>
|
||||
<td><a href="https://twistag.com/" target="_blank"><img src="https://nestjs.com/img/twistag-logo.png" width="120" valign="middle" /></td>
|
||||
</tr>
|
||||
<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://www.myleodsc.com/" target="_blank"><img src="https://nestjs.com/img/myleo-logo.png" width="180" valign="middle" /></td><td>
|
||||
<a href="https://careers.meetdandy.com/?gh_src=063ba61e3us" target="_blank"><img src="https://nestjs.com/img/dandy-roles-logo.svg" width="150" valign="middle" /></td><td>
|
||||
<a href="https://www.castlecraft.in" target="_blank"><img src="https://nestjs.com/img/castlecraft-logo.png" width="150" valign="middle" /></td>
|
||||
<td><a href="https://www.tinystacks.com" target="_blank"><img src="https://nestjs.com/img/tinystacks-logo.png#1" width="140" valign="middle" /></td>
|
||||
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td></tr><tr>
|
||||
<td><a href="https://bilberrry.com/" target="_blank"><img src="https://nestjs.com/img/bilberrry-logo.svg" width="180" valign="middle" /></td>
|
||||
<td><a href="https://ipinfo.ai/" target="_blank"><img src="https://nestjs.com/img/ipinfo-logo.png" width="130" valign="middle" /></td>
|
||||
<td><a href="https://chax.at" target="_blank"><img src="https://nestjs.com/img/chaxat-logo.png" width="100" valign="middle" /></td></tr>
|
||||
</table>
|
||||
|
||||
#### Sponsors
|
||||
@@ -101,26 +102,41 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<table><tr><td align="center" valign="middle">
|
||||
<a href="https://www.swingdev.io" target="_blank"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="110" valign="middle" /> </a></td><td align="center" valign="middle">
|
||||
<a href="https://www.novologic.com/" target="_blank"><img src="https://nestjs.com/img/novologic.png" width="110" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://ever.co/" target="_blank"><img src="https://nestjs.com/img/ever-logo.png" width="72" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://blokt.com" target="_blank"><img src="https://nestjs.com/img/blokt-logo.png" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="http://architectnow.net/" target="_blank"><img src="https://nestjs.com/img/architectnow.png" width="125" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://quander.io/" target="_blank"><img src="https://nestjs.com/img/quander.png" width="100" valign="middle" /></a> </td></tr><tr><td align="center" valign="middle">
|
||||
<a href="https://mantro.net/" target="_blank"><img src="https://nestjs.com/img/mantro-logo.svg" width="95" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://triplebyte.com/" target="_blank"><img src="https://nestjs.com/img/triplebyte.png" width="107" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td>
|
||||
<a href="https://reposit.co.uk/" target="_blank"><img src="https://nestjs.com/img/reposit-logo.png" width="71" valign="middle" /></a></td><td align="center" valign="middle">
|
||||
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://clay.global/" target="_blank"><img src="https://nestjs.com/img/clay-logo.svg" width="75" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://firesticktricks.com" target="_blank"><img src="https://nestjs.com/img/firesticktricks-logo.png" width="120" valign="middle" /></a></td></tr><tr><td align="center" valign="middle">
|
||||
<a href="https://www.codeguesser.co.uk" target="_blank"><img src="https://nestjs.com/img/codeguesser-logo.svg" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://f-a.nz/" target="_blank"><img src="https://nestjs.com/img/franz.svg" width="80" valign="middle" /></a> </td><td align="center" valign="middle">
|
||||
<a href="https://sparkfabrik.com/" target="_blank"><img src="https://nestjs.com/img/sparkfabrik-logo.png" width="120" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://www.thebigphonestore.co.uk/" target="_blank"><img src="https://nestjs.com/img/the-big-phone-store-logo.png" width="65" valign="middle" /></a></td>
|
||||
<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></tr><tr>
|
||||
<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><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://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<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://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></tr><tr>
|
||||
<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>
|
||||
<td align="center" valign="middle"><a href="https://houseofangular.io/" target="_blank"><img src="https://nestjs.com/img/house-of-angular.png" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://rocketech.it/cases/?utm_source=google&utm_medium=badge&utm_campaign=nestjs" target="_blank"><img src="https://nestjs.com/img/rocketech-logo.svg" width="110" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.bystored.com/" target="_blank"><img src="https://nestjs.com/img/stored-logo.svg" width="110" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://studyclerk.com/pay-for-research-paper" target="_blank"><img src="https://nestjs.com/img/studyclerk-logo.png" width="125" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://xyndata.com" target="_blank"><img src="https://nestjs.com/img/xyndata-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.naologic.com/" target="_blank"><img src="https://nestjs.com/img/naologic-logo.svg" width="125" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://messaged.com/" target="_blank"><img src="https://nestjs.com/img/messaged-logo.png" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://triplecore.io" target="_blank"><img src="https://nestjs.com/img/triplecore-logo.svg" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://klqc.de" target="_blank"><img src="https://nestjs.com/img/klcqcl-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://polygon-software.ch/" target="_blank"><img src="https://nestjs.com/img/polygon-logo.svg" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://themobilereality.com/" target="_blank"><img src="https://nestjs.com/img/mobile-reality-logo.png" width="45" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://boringowl.io/" target="_blank"><img src="https://nestjs.com/img/boringowl-logo.svg" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/nordbot-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://www.mobilefactory.jp/" target="_blank"><img src="https://nestjs.com/img/mobilefactory-logo.png" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/nordbot-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/dopiosh-logo.png" width="50" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.hingehealth.com/" target="_blank"><img src="https://nestjs.com/img/hinge-health-logo.svg" width="100" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://julienferand.dev/" target="_blank"><img src="https://nestjs.com/img/julienferand-logo.jpeg" width="65" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.tripoffice.com/" target="_blank"><img src="https://nestjs.com/img/tripoffice-logo.png" width="140" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://solcellsforetag.se/" target="_blank"><img src="https://nestjs.com/img/solcellsforetag-logo.svg" width="140" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
@@ -129,9 +145,9 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
## Stay in touch
|
||||
|
||||
- Author - [Kamil Myśliwiec](https://x.com/kammysliwiec)
|
||||
- Website - [https://nestjs.com](https://nestjs.com/)
|
||||
- X - [@nestframework](https://x.com/nestframework)
|
||||
* Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||
* Website - [https://nestjs.com](https://nestjs.com/)
|
||||
* Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -158,15 +158,15 @@ export function Controller(
|
||||
)
|
||||
? [defaultPath, undefined, undefined, undefined]
|
||||
: isString(prefixOrOptions) || Array.isArray(prefixOrOptions)
|
||||
? [prefixOrOptions, undefined, undefined, undefined]
|
||||
: [
|
||||
prefixOrOptions.path || defaultPath,
|
||||
prefixOrOptions.host,
|
||||
{ scope: prefixOrOptions.scope, durable: prefixOrOptions.durable },
|
||||
Array.isArray(prefixOrOptions.version)
|
||||
? Array.from(new Set(prefixOrOptions.version))
|
||||
: prefixOrOptions.version,
|
||||
];
|
||||
? [prefixOrOptions, undefined, undefined, undefined]
|
||||
: [
|
||||
prefixOrOptions.path || defaultPath,
|
||||
prefixOrOptions.host,
|
||||
{ scope: prefixOrOptions.scope, durable: prefixOrOptions.durable },
|
||||
Array.isArray(prefixOrOptions.version)
|
||||
? Array.from(new Set(prefixOrOptions.version))
|
||||
: prefixOrOptions.version,
|
||||
];
|
||||
|
||||
return (target: object) => {
|
||||
Reflect.defineMetadata(CONTROLLER_WATERMARK, true, target);
|
||||
|
||||
@@ -39,12 +39,6 @@ export function Inject<T = any>(
|
||||
return (target: object, key: string | symbol | undefined, index?: number) => {
|
||||
const type = token || Reflect.getMetadata('design:type', target, key);
|
||||
|
||||
if (!type) {
|
||||
throw new Error(`Token is undefined at index: ${index}. This often occurs due to circular dependencies.
|
||||
Ensure there are no circular dependencies in your files or barrel files.
|
||||
For more details, refer to https://trilon.io/blog/avoiding-circular-dependencies-in-nestjs.`);
|
||||
}
|
||||
|
||||
if (!isUndefined(index)) {
|
||||
let dependencies =
|
||||
Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, target) || [];
|
||||
|
||||
@@ -15,7 +15,7 @@ export type CustomDecorator<TKey = string> = MethodDecorator &
|
||||
*
|
||||
* Example: `@SetMetadata('roles', ['admin'])`
|
||||
*
|
||||
* @see [Reflection](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)
|
||||
* @see [Reflection](https://docs.nestjs.com/guards#reflection)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@ export type ParamDecoratorEnhancer = ParameterDecorator;
|
||||
* Defines HTTP route param decorator
|
||||
*
|
||||
* @param factory
|
||||
* @param enhancers
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import { extendArrayMetadata } from '../../utils/extend-metadata.util';
|
||||
*
|
||||
* For example:
|
||||
* `@Header('Cache-Control', 'none')`
|
||||
* `@Header('Cache-Control', () => 'none')`
|
||||
*
|
||||
* @param name string to be used for header name
|
||||
* @param value string to be used for header value
|
||||
@@ -15,10 +14,7 @@ import { extendArrayMetadata } from '../../utils/extend-metadata.util';
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function Header(
|
||||
name: string,
|
||||
value: string | (() => string),
|
||||
): MethodDecorator {
|
||||
export function Header(name: string, value: string): MethodDecorator {
|
||||
return (
|
||||
target: object,
|
||||
key: string | symbol,
|
||||
|
||||
@@ -111,7 +111,7 @@ export const Head = createMappingDecorator(RequestMethod.HEAD);
|
||||
export const All = createMappingDecorator(RequestMethod.ALL);
|
||||
|
||||
/**
|
||||
* Route handler (method) Decorator. Routes HTTP SEARCH requests to the specified path.
|
||||
* Route handler (method) Decorator. Routes all HTTP requests to the specified path.
|
||||
*
|
||||
* @see [Routing](https://docs.nestjs.com/controllers#routing)
|
||||
*
|
||||
|
||||
@@ -508,53 +508,6 @@ export function Body(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `rawBody` Buffer
|
||||
* property from the `req` object and populates the decorated parameter with that value.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* async create(@RawBody() rawBody: Buffer | undefined)
|
||||
* ```
|
||||
*
|
||||
* @see [Request object](https://docs.nestjs.com/controllers#request-object)
|
||||
* @see [Raw body](https://docs.nestjs.com/faq/raw-body)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function RawBody(): ParameterDecorator;
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `rawBody` Buffer
|
||||
* property from the `req` object and populates the decorated parameter with that value.
|
||||
* Also applies pipes to the bound rawBody parameter.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* async create(@RawBody(new ValidationPipe()) rawBody: Buffer)
|
||||
* ```
|
||||
*
|
||||
* @param pipes one or more pipes - either instances or classes - to apply to
|
||||
* the bound body parameter.
|
||||
*
|
||||
* @see [Request object](https://docs.nestjs.com/controllers#request-object)
|
||||
* @see [Raw body](https://docs.nestjs.com/faq/raw-body)
|
||||
* @see [Working with pipes](https://docs.nestjs.com/custom-decorators#working-with-pipes)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function RawBody(
|
||||
...pipes: (
|
||||
| Type<PipeTransform<Buffer | undefined>>
|
||||
| PipeTransform<Buffer | undefined>
|
||||
)[]
|
||||
): ParameterDecorator {
|
||||
return createPipesRouteParamDecorator(RouteParamtypes.RAW_BODY)(
|
||||
undefined,
|
||||
...pipes,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `params`
|
||||
* property from the `req` object and populates the decorated
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
export enum RouteParamtypes {
|
||||
REQUEST = 0,
|
||||
RESPONSE = 1,
|
||||
NEXT = 2,
|
||||
BODY = 3,
|
||||
QUERY = 4,
|
||||
PARAM = 5,
|
||||
HEADERS = 6,
|
||||
SESSION = 7,
|
||||
FILE = 8,
|
||||
FILES = 9,
|
||||
HOST = 10,
|
||||
IP = 11,
|
||||
RAW_BODY = 12,
|
||||
REQUEST,
|
||||
RESPONSE,
|
||||
NEXT,
|
||||
BODY,
|
||||
QUERY,
|
||||
PARAM,
|
||||
HEADERS,
|
||||
SESSION,
|
||||
FILE,
|
||||
FILES,
|
||||
HOST,
|
||||
IP,
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@ import {
|
||||
import { isObject, isString } from '../utils/shared.utils';
|
||||
|
||||
export interface HttpExceptionOptions {
|
||||
/** original cause of the error */
|
||||
cause?: unknown;
|
||||
cause?: Error;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
@@ -28,6 +27,7 @@ export class HttpException extends Error {
|
||||
* Instantiate a plain HTTP Exception.
|
||||
*
|
||||
* @example
|
||||
* throw new HttpException()
|
||||
* throw new HttpException('message', HttpStatus.BAD_REQUEST)
|
||||
* throw new HttpException('custom message', HttpStatus.BAD_REQUEST, {
|
||||
* cause: new Error('Cause Error'),
|
||||
@@ -68,13 +68,14 @@ export class HttpException extends Error {
|
||||
this.initCause();
|
||||
}
|
||||
|
||||
public cause: unknown;
|
||||
public cause: Error | undefined;
|
||||
|
||||
/**
|
||||
* Configures error chaining support
|
||||
*
|
||||
* @see https://nodejs.org/en/blog/release/v16.9.0/#error-cause
|
||||
* @see https://github.com/microsoft/TypeScript/issues/45167
|
||||
* See:
|
||||
* - https://nodejs.org/en/blog/release/v16.9.0/#error-cause
|
||||
* - https://github.com/microsoft/TypeScript/issues/45167
|
||||
*/
|
||||
public initCause(): void {
|
||||
if (this.options?.cause) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { types } from 'util';
|
||||
import { HttpStatus } from '../enums';
|
||||
import { isFunction } from '../utils/shared.utils';
|
||||
import { StreamableFileOptions, StreamableHandlerResponse } from './interfaces';
|
||||
import { Logger } from '../services';
|
||||
|
||||
/**
|
||||
* @see [Streaming files](https://docs.nestjs.com/techniques/streaming-files)
|
||||
@@ -12,7 +11,6 @@ import { Logger } from '../services';
|
||||
*/
|
||||
export class StreamableFile {
|
||||
private readonly stream: Readable;
|
||||
protected logger = new Logger('StreamableFile');
|
||||
|
||||
protected handleError: (
|
||||
err: Error,
|
||||
@@ -30,10 +28,6 @@ export class StreamableFile {
|
||||
res.send(err.message);
|
||||
};
|
||||
|
||||
protected logError: (err: Error) => void = (err: Error) => {
|
||||
this.logger.error(err.message, err.stack);
|
||||
};
|
||||
|
||||
constructor(buffer: Uint8Array, options?: StreamableFileOptions);
|
||||
constructor(readable: Readable, options?: StreamableFileOptions);
|
||||
constructor(
|
||||
@@ -80,13 +74,4 @@ export class StreamableFile {
|
||||
this.handleError = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
get errorLogger() {
|
||||
return this.logError;
|
||||
}
|
||||
|
||||
setErrorLogger(handler: (err: Error) => void) {
|
||||
this.logError = handler;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ export {
|
||||
HttpServer,
|
||||
HttpExceptionBody,
|
||||
HttpExceptionBodyMessage,
|
||||
HttpRedirectResponse,
|
||||
INestApplication,
|
||||
INestApplicationContext,
|
||||
INestMicroservice,
|
||||
|
||||
@@ -56,7 +56,7 @@ export interface CorsOptions {
|
||||
}
|
||||
|
||||
export interface CorsOptionsCallback {
|
||||
(error: Error | null, options: CorsOptions): void;
|
||||
(error: Error, options: CorsOptions): void;
|
||||
}
|
||||
export interface CorsOptionsDelegate<T> {
|
||||
(req: T, cb: CorsOptionsCallback): void;
|
||||
|
||||
@@ -96,10 +96,4 @@ export interface HttpsOptions {
|
||||
* the default callback with high-level API will be used.
|
||||
*/
|
||||
SNICallback?: (servername: string, cb: (err: Error, ctx: any) => any) => any;
|
||||
/**
|
||||
* Optionally affect the OpenSSL protocol behavior, which is not usually necessary.
|
||||
* This should be used carefully if at all! Value is a numeric bitmask of the SSL_OP_* options
|
||||
* from OpenSSL Options.
|
||||
*/
|
||||
secureOptions?: number;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,6 @@ export interface WsArgumentsHost {
|
||||
* Returns the client object.
|
||||
*/
|
||||
getClient<T = any>(): T;
|
||||
/**
|
||||
* Returns the pattern for the event
|
||||
*/
|
||||
getPattern(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { HttpStatus } from '../../enums';
|
||||
|
||||
export interface HttpRedirectResponse {
|
||||
url: string;
|
||||
statusCode: HttpStatus;
|
||||
}
|
||||
@@ -51,8 +51,6 @@ export interface HttpServer<
|
||||
all(handler: RequestHandler<TRequest, TResponse>): any;
|
||||
options(handler: RequestHandler<TRequest, TResponse>): any;
|
||||
options(path: string, handler: RequestHandler<TRequest, TResponse>): any;
|
||||
search?(handler: RequestHandler<TRequest, TResponse>): any;
|
||||
search?(path: string, handler: RequestHandler<TRequest, TResponse>): any;
|
||||
listen(port: number | string, callback?: () => void): any;
|
||||
listen(port: number | string, hostname: string, callback?: () => void): any;
|
||||
reply(response: any, body: any, statusCode?: number): any;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export * from './http-exception-body.interface';
|
||||
export * from './http-redirect-response.interface';
|
||||
export * from './http-server.interface';
|
||||
export * from './message-event.interface';
|
||||
export * from './raw-body-request.interface';
|
||||
|
||||
@@ -20,7 +20,7 @@ import { generateOptionsInjectionToken, getInjectionProviders } from './utils';
|
||||
*/
|
||||
export interface ConfigurableModuleBuilderOptions {
|
||||
/**
|
||||
* Specifies what injection token should be used for the module options provider.
|
||||
* Specified what injection token should be used for the module options provider.
|
||||
* By default, an auto-generated UUID will be used.
|
||||
*/
|
||||
optionsInjectionToken?: string | symbol;
|
||||
@@ -29,11 +29,11 @@ export interface ConfigurableModuleBuilderOptions {
|
||||
* Explicitly specifying the "moduleName" will instruct the "ConfigurableModuleBuilder"
|
||||
* to use a more descriptive provider token.
|
||||
*
|
||||
* For example, `moduleName: "Cache"` will auto-generate the provider token: "CACHE_MODULE_OPTIONS".
|
||||
* For example, if `moduleName: "Cache"` then auto-generated provider token will be "CACHE_MODULE_OPTIONS".
|
||||
*/
|
||||
moduleName?: string;
|
||||
/**
|
||||
* Indicates whether module should always be "transient" - meaning,
|
||||
* Indicates whether module should always be "transient", meaning,
|
||||
* every time you call the static method to construct a dynamic module,
|
||||
* regardless of what arguments you pass in, a new "unique" module will be created.
|
||||
*
|
||||
@@ -51,8 +51,7 @@ export interface ConfigurableModuleBuilderOptions {
|
||||
export class ConfigurableModuleBuilder<
|
||||
ModuleOptions,
|
||||
StaticMethodKey extends string = typeof DEFAULT_METHOD_KEY,
|
||||
FactoryClassMethodKey extends
|
||||
string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
FactoryClassMethodKey extends string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
ExtraModuleDefinitionOptions = {},
|
||||
> {
|
||||
protected staticMethodKey: StaticMethodKey;
|
||||
|
||||
@@ -28,8 +28,7 @@ export type ConfigurableModuleOptionsFactory<
|
||||
*/
|
||||
export interface ConfigurableModuleAsyncOptions<
|
||||
ModuleOptions,
|
||||
FactoryClassMethodKey extends
|
||||
string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
FactoryClassMethodKey extends string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
> extends Pick<ModuleMetadata, 'imports'> {
|
||||
/**
|
||||
* Injection token resolving to an existing provider. The provider must implement
|
||||
|
||||
@@ -15,8 +15,7 @@ import { ConfigurableModuleAsyncOptions } from './configurable-module-async-opti
|
||||
export type ConfigurableModuleCls<
|
||||
ModuleOptions,
|
||||
MethodKey extends string = typeof DEFAULT_METHOD_KEY,
|
||||
FactoryClassMethodKey extends
|
||||
string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
FactoryClassMethodKey extends string = typeof DEFAULT_FACTORY_CLASS_METHOD_KEY,
|
||||
ExtraModuleDefinitionOptions = {},
|
||||
> = {
|
||||
new (): any;
|
||||
|
||||
@@ -42,7 +42,8 @@ export function getInjectionProviders(
|
||||
// get injection tokens of the matched providers, if any
|
||||
search = match
|
||||
.filter(p => (p as any)?.inject)
|
||||
.flatMap(p => (p as FactoryProvider).inject)
|
||||
.map(p => (p as FactoryProvider).inject)
|
||||
.flat()
|
||||
.map(mapInjectToTokens);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/common",
|
||||
"version": "10.3.5",
|
||||
"version": "9.4.2",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@common)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"homepage": "https://nestjs.com",
|
||||
@@ -19,13 +19,13 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"iterare": "1.2.1",
|
||||
"tslib": "2.6.2",
|
||||
"tslib": "2.5.2",
|
||||
"uid": "2.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"class-transformer": "*",
|
||||
"class-validator": "*",
|
||||
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"rxjs": "^7.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
|
||||
@@ -16,21 +16,17 @@ export type FileTypeValidatorOptions = {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export class FileTypeValidator extends FileValidator<
|
||||
FileTypeValidatorOptions,
|
||||
IFile
|
||||
> {
|
||||
export class FileTypeValidator extends FileValidator<FileTypeValidatorOptions> {
|
||||
buildErrorMessage(): string {
|
||||
return `Validation failed (expected type is ${this.validationOptions.fileType})`;
|
||||
}
|
||||
|
||||
isValid(file?: IFile): boolean {
|
||||
isValid<TFile extends IFile = any>(file: TFile): boolean {
|
||||
if (!this.validationOptions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
!!file &&
|
||||
'mimetype' in file &&
|
||||
!!file.mimetype.match(this.validationOptions.fileType)
|
||||
);
|
||||
|
||||
@@ -6,18 +6,15 @@ import { IFile } from './interfaces';
|
||||
* @see {ParseFilePipe}
|
||||
* @publicApi
|
||||
*/
|
||||
export abstract class FileValidator<
|
||||
TValidationOptions = Record<string, any>,
|
||||
TFile extends IFile = IFile,
|
||||
> {
|
||||
export abstract class FileValidator<TValidationOptions = Record<string, any>> {
|
||||
constructor(protected readonly validationOptions: TValidationOptions) {}
|
||||
|
||||
/**
|
||||
* Indicates if this file should be considered valid, according to the options passed in the constructor.
|
||||
* @param file the file from the request object
|
||||
*/
|
||||
abstract isValid(
|
||||
file?: TFile | TFile[] | Record<string, TFile[]>,
|
||||
abstract isValid<TFile extends IFile = any>(
|
||||
file?: TFile,
|
||||
): boolean | Promise<boolean>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,10 +13,7 @@ export type MaxFileSizeValidatorOptions = {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export class MaxFileSizeValidator extends FileValidator<
|
||||
MaxFileSizeValidatorOptions,
|
||||
IFile
|
||||
> {
|
||||
export class MaxFileSizeValidator extends FileValidator<MaxFileSizeValidatorOptions> {
|
||||
buildErrorMessage(): string {
|
||||
if ('message' in this.validationOptions) {
|
||||
if (typeof this.validationOptions.message === 'function') {
|
||||
@@ -29,8 +26,8 @@ export class MaxFileSizeValidator extends FileValidator<
|
||||
return `Validation failed (expected size is less than ${this.validationOptions.maxSize})`;
|
||||
}
|
||||
|
||||
public isValid(file?: IFile): boolean {
|
||||
if (!this.validationOptions || !file) {
|
||||
public isValid<TFile extends IFile = any>(file: TFile): boolean {
|
||||
if (!this.validationOptions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
ErrorHttpStatusCode,
|
||||
HttpErrorByCode,
|
||||
} from '../utils/http-error-by-code.util';
|
||||
import { isNil } from '../utils/shared.utils';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@@ -17,7 +16,6 @@ import { isNil } from '../utils/shared.utils';
|
||||
export interface ParseBoolPipeOptions {
|
||||
errorHttpStatusCode?: ErrorHttpStatusCode;
|
||||
exceptionFactory?: (error: string) => any;
|
||||
optional?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,7 +31,7 @@ export class ParseBoolPipe
|
||||
{
|
||||
protected exceptionFactory: (error: string) => any;
|
||||
|
||||
constructor(@Optional() protected readonly options?: ParseBoolPipeOptions) {
|
||||
constructor(@Optional() options?: ParseBoolPipeOptions) {
|
||||
options = options || {};
|
||||
const { exceptionFactory, errorHttpStatusCode = HttpStatus.BAD_REQUEST } =
|
||||
options;
|
||||
@@ -53,9 +51,6 @@ export class ParseBoolPipe
|
||||
value: string | boolean,
|
||||
metadata: ArgumentMetadata,
|
||||
): Promise<boolean> {
|
||||
if (isNil(value) && this.options?.optional) {
|
||||
return value;
|
||||
}
|
||||
if (this.isTrue(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import { Injectable, Optional } from '../decorators/core';
|
||||
import { ArgumentMetadata, HttpStatus } from '../index';
|
||||
import { ArgumentMetadata, HttpStatus, Injectable, Optional } from '../index';
|
||||
import { PipeTransform } from '../interfaces/features/pipe-transform.interface';
|
||||
import {
|
||||
ErrorHttpStatusCode,
|
||||
HttpErrorByCode,
|
||||
} from '../utils/http-error-by-code.util';
|
||||
import { isNil } from '../utils/shared.utils';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
*/
|
||||
export interface ParseEnumPipeOptions {
|
||||
optional?: boolean;
|
||||
errorHttpStatusCode?: ErrorHttpStatusCode;
|
||||
exceptionFactory?: (error: string) => any;
|
||||
}
|
||||
@@ -26,9 +23,10 @@ export interface ParseEnumPipeOptions {
|
||||
@Injectable()
|
||||
export class ParseEnumPipe<T = any> implements PipeTransform<T> {
|
||||
protected exceptionFactory: (error: string) => any;
|
||||
|
||||
constructor(
|
||||
protected readonly enumType: T,
|
||||
@Optional() protected readonly options?: ParseEnumPipeOptions,
|
||||
@Optional() options?: ParseEnumPipeOptions,
|
||||
) {
|
||||
if (!enumType) {
|
||||
throw new Error(
|
||||
@@ -52,9 +50,6 @@ export class ParseEnumPipe<T = any> implements PipeTransform<T> {
|
||||
* @param metadata contains metadata about the currently processed route argument
|
||||
*/
|
||||
async transform(value: T, metadata: ArgumentMetadata): Promise<T> {
|
||||
if (isNil(value) && this.options?.optional) {
|
||||
return value;
|
||||
}
|
||||
if (!this.isEnum(value)) {
|
||||
throw this.exceptionFactory(
|
||||
'Validation failed (enum string is expected)',
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Injectable, Optional } from '../decorators/core';
|
||||
import { ArgumentMetadata, HttpStatus } from '../index';
|
||||
import { Injectable, Optional } from '../decorators/core';
|
||||
import { PipeTransform } from '../interfaces/features/pipe-transform.interface';
|
||||
import {
|
||||
ErrorHttpStatusCode,
|
||||
HttpErrorByCode,
|
||||
} from '../utils/http-error-by-code.util';
|
||||
import { isNil } from '../utils/shared.utils';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@@ -13,7 +12,6 @@ import { isNil } from '../utils/shared.utils';
|
||||
export interface ParseFloatPipeOptions {
|
||||
errorHttpStatusCode?: ErrorHttpStatusCode;
|
||||
exceptionFactory?: (error: string) => any;
|
||||
optional?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,7 +25,7 @@ export interface ParseFloatPipeOptions {
|
||||
export class ParseFloatPipe implements PipeTransform<string> {
|
||||
protected exceptionFactory: (error: string) => any;
|
||||
|
||||
constructor(@Optional() protected readonly options?: ParseFloatPipeOptions) {
|
||||
constructor(@Optional() options?: ParseFloatPipeOptions) {
|
||||
options = options || {};
|
||||
const { exceptionFactory, errorHttpStatusCode = HttpStatus.BAD_REQUEST } =
|
||||
options;
|
||||
@@ -45,9 +43,6 @@ export class ParseFloatPipe implements PipeTransform<string> {
|
||||
* @param metadata contains metadata about the currently processed route argument
|
||||
*/
|
||||
async transform(value: string, metadata: ArgumentMetadata): Promise<number> {
|
||||
if (isNil(value) && this.options?.optional) {
|
||||
return value;
|
||||
}
|
||||
if (!this.isNumeric(value)) {
|
||||
throw this.exceptionFactory(
|
||||
'Validation failed (numeric string is expected)',
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
ErrorHttpStatusCode,
|
||||
HttpErrorByCode,
|
||||
} from '../utils/http-error-by-code.util';
|
||||
import { isNil } from '../utils/shared.utils';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@@ -17,7 +16,6 @@ import { isNil } from '../utils/shared.utils';
|
||||
export interface ParseIntPipeOptions {
|
||||
errorHttpStatusCode?: ErrorHttpStatusCode;
|
||||
exceptionFactory?: (error: string) => any;
|
||||
optional?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,7 @@ export interface ParseIntPipeOptions {
|
||||
export class ParseIntPipe implements PipeTransform<string> {
|
||||
protected exceptionFactory: (error: string) => any;
|
||||
|
||||
constructor(@Optional() protected readonly options?: ParseIntPipeOptions) {
|
||||
constructor(@Optional() options?: ParseIntPipeOptions) {
|
||||
options = options || {};
|
||||
const { exceptionFactory, errorHttpStatusCode = HttpStatus.BAD_REQUEST } =
|
||||
options;
|
||||
@@ -49,9 +47,6 @@ export class ParseIntPipe implements PipeTransform<string> {
|
||||
* @param metadata contains metadata about the currently processed route argument
|
||||
*/
|
||||
async transform(value: string, metadata: ArgumentMetadata): Promise<number> {
|
||||
if (isNil(value) && this.options?.optional) {
|
||||
return value;
|
||||
}
|
||||
if (!this.isNumeric(value)) {
|
||||
throw this.exceptionFactory(
|
||||
'Validation failed (numeric string is expected)',
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
ErrorHttpStatusCode,
|
||||
HttpErrorByCode,
|
||||
} from '../utils/http-error-by-code.util';
|
||||
import { isNil, isString } from '../utils/shared.utils';
|
||||
import { isString } from '../utils/shared.utils';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@@ -18,7 +18,6 @@ export interface ParseUUIDPipeOptions {
|
||||
version?: '3' | '4' | '5';
|
||||
errorHttpStatusCode?: ErrorHttpStatusCode;
|
||||
exceptionFactory?: (errors: string) => any;
|
||||
optional?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +38,7 @@ export class ParseUUIDPipe implements PipeTransform<string> {
|
||||
private readonly version: '3' | '4' | '5';
|
||||
protected exceptionFactory: (errors: string) => any;
|
||||
|
||||
constructor(@Optional() protected readonly options?: ParseUUIDPipeOptions) {
|
||||
constructor(@Optional() options?: ParseUUIDPipeOptions) {
|
||||
options = options || {};
|
||||
const {
|
||||
exceptionFactory,
|
||||
@@ -54,9 +53,6 @@ export class ParseUUIDPipe implements PipeTransform<string> {
|
||||
}
|
||||
|
||||
async transform(value: string, metadata: ArgumentMetadata): Promise<string> {
|
||||
if (isNil(value) && this.options?.optional) {
|
||||
return value;
|
||||
}
|
||||
if (!this.isUUID(value, this.version)) {
|
||||
throw this.exceptionFactory(
|
||||
`Validation failed (uuid${
|
||||
|
||||
@@ -179,7 +179,7 @@ export class ValidationPipe implements PipeTransform<any> {
|
||||
if (type === 'custom' && !this.validateCustomDecorators) {
|
||||
return false;
|
||||
}
|
||||
const types = [String, Boolean, Number, Array, Object, Buffer, Date];
|
||||
const types = [String, Boolean, Number, Array, Object, Buffer];
|
||||
return !types.some(t => metatype === t) && !isNil(metatype);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ const DEFAULT_LOG_LEVELS: LogLevel[] = [
|
||||
'warn',
|
||||
'debug',
|
||||
'verbose',
|
||||
'fatal',
|
||||
];
|
||||
|
||||
const dateTimeFormatter = new Intl.DateTimeFormat(undefined, {
|
||||
@@ -146,23 +145,6 @@ export class ConsoleLogger implements LoggerService {
|
||||
this.printMessages(messages, context, 'verbose');
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a 'fatal' level log, if the configured level allows for it.
|
||||
* Prints to `stdout` with newline.
|
||||
*/
|
||||
fatal(message: any, context?: string): void;
|
||||
fatal(message: any, ...optionalParams: [...any, string?]): void;
|
||||
fatal(message: any, ...optionalParams: any[]) {
|
||||
if (!this.isLevelEnabled('fatal')) {
|
||||
return;
|
||||
}
|
||||
const { messages, context } = this.getContextAndMessagesToPrint([
|
||||
message,
|
||||
...optionalParams,
|
||||
]);
|
||||
this.printMessages(messages, context, 'fatal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set log levels
|
||||
* @param levels log levels
|
||||
@@ -245,18 +227,10 @@ export class ConsoleLogger implements LoggerService {
|
||||
}
|
||||
|
||||
protected stringifyMessage(message: unknown, logLevel: LogLevel) {
|
||||
if (isFunction(message)) {
|
||||
const messageAsStr = Function.prototype.toString.call(message);
|
||||
const isClass = messageAsStr.startsWith('class ');
|
||||
if (isClass) {
|
||||
// If the message is a class, we will display the class name.
|
||||
return this.stringifyMessage(message.name, logLevel);
|
||||
}
|
||||
// If the message is a non-class function, call it and re-resolve its value.
|
||||
return this.stringifyMessage(message(), logLevel);
|
||||
}
|
||||
|
||||
return isPlainObject(message) || Array.isArray(message)
|
||||
// If the message is a function, call it and re-resolve its value.
|
||||
return isFunction(message)
|
||||
? this.stringifyMessage(message(), logLevel)
|
||||
: isPlainObject(message) || Array.isArray(message)
|
||||
? `${this.colorize('Object:', logLevel)}\n${JSON.stringify(
|
||||
message,
|
||||
(key, value) =>
|
||||
@@ -343,7 +317,7 @@ export class ConsoleLogger implements LoggerService {
|
||||
return false;
|
||||
}
|
||||
|
||||
return /^(.)+\n\s+at .+:\d+:\d+/.test(stack);
|
||||
return /^(.)+\n\s+at .+:\d+:\d+$/.test(stack);
|
||||
}
|
||||
|
||||
private getColorByLogLevel(level: LogLevel) {
|
||||
@@ -356,8 +330,6 @@ export class ConsoleLogger implements LoggerService {
|
||||
return clc.red;
|
||||
case 'verbose':
|
||||
return clc.cyanBright;
|
||||
case 'fatal':
|
||||
return clc.bold;
|
||||
default:
|
||||
return clc.green;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isLogLevelEnabled } from './utils';
|
||||
/**
|
||||
* @publicApi
|
||||
*/
|
||||
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose' | 'fatal';
|
||||
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@@ -37,11 +37,6 @@ export interface LoggerService {
|
||||
*/
|
||||
verbose?(message: any, ...optionalParams: any[]): any;
|
||||
|
||||
/**
|
||||
* Write a 'fatal' level log.
|
||||
*/
|
||||
fatal?(message: any, ...optionalParams: any[]): any;
|
||||
|
||||
/**
|
||||
* Set log levels.
|
||||
* @param levels log levels
|
||||
@@ -190,19 +185,6 @@ export class Logger implements LoggerService {
|
||||
this.localInstance?.verbose?.(message, ...optionalParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a 'fatal' level log.
|
||||
*/
|
||||
fatal(message: any, context?: string): void;
|
||||
fatal(message: any, ...optionalParams: [...any, string?]): void;
|
||||
@Logger.WrapBuffer
|
||||
fatal(message: any, ...optionalParams: any[]) {
|
||||
optionalParams = this.context
|
||||
? optionalParams.concat(this.context)
|
||||
: optionalParams;
|
||||
this.localInstance?.fatal?.(message, ...optionalParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an 'error' level log.
|
||||
*/
|
||||
@@ -259,16 +241,6 @@ export class Logger implements LoggerService {
|
||||
this.staticInstanceRef?.verbose?.(message, ...optionalParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a 'fatal' level log.
|
||||
*/
|
||||
static fatal(message: any, context?: string): void;
|
||||
static fatal(message: any, ...optionalParams: [...any, string?]): void;
|
||||
@Logger.WrapBuffer
|
||||
static fatal(message: any, ...optionalParams: any[]) {
|
||||
this.staticInstanceRef?.fatal?.(message, ...optionalParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print buffered logs and detach buffer.
|
||||
*/
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { LogLevel } from '../logger.service';
|
||||
|
||||
const LOG_LEVEL_VALUES: Record<LogLevel, number> = {
|
||||
verbose: 0,
|
||||
debug: 1,
|
||||
debug: 0,
|
||||
verbose: 1,
|
||||
log: 2,
|
||||
warn: 3,
|
||||
error: 4,
|
||||
fatal: 5,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user