@nestjs/common 9.0.0-next.1 → 9.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Readme.md CHANGED
@@ -65,19 +65,20 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
65
65
  <td>
66
66
  <a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" valign="middle" /></a></td>
67
67
  <td>
68
- <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>
68
+ <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>
69
+ <a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
69
70
  </tr></table>
70
71
 
71
72
  #### Gold Sponsors
72
73
 
73
74
  <table style="text-align:center;"><tr><td>
74
- <a href="https://careers.labster.com/departments/platform" target="_blank"><img src="https://nestjs.com/img/labster-logo.png" width="170" valign="middle" /></a></td><td>
75
75
  <a href="https://weld.app/" target="_blank"><img src="https://nestjs.com/img/weld-logo.svg" width="140" valign="middle" /></a></td>
76
76
  <td>
77
77
  <a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td>
78
78
  <td>
79
79
  <a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="110" valign="middle" /></a></td><td>
80
- <a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/snyk-logo-black.png" width="185" valign="middle" /></a></td></</tr></table>
80
+ <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>
81
+ <a href="https://fuseautotech.com/" target="_blank"><img src="https://nestjs.com/img/fuse-logo.svg" width="105" valign="middle" /></a></td></</tr></table>
81
82
 
82
83
  #### Silver Sponsors
83
84
 
@@ -35,6 +35,15 @@ export declare class HttpException extends Error {
35
35
  * @param status HTTP response status code.
36
36
  */
37
37
  constructor(response: string | Record<string, any>, status: number);
38
+ cause: Error | undefined;
39
+ /**
40
+ * Configures error chaining support
41
+ *
42
+ * See:
43
+ * - https://nodejs.org/en/blog/release/v16.9.0/#error-cause
44
+ * - https://github.com/microsoft/TypeScript/issues/45167
45
+ */
46
+ initCause(): void;
38
47
  initMessage(): void;
39
48
  initName(): void;
40
49
  getResponse(): string | object;
@@ -42,6 +42,19 @@ class HttpException extends Error {
42
42
  this.status = status;
43
43
  this.initMessage();
44
44
  this.initName();
45
+ this.initCause();
46
+ }
47
+ /**
48
+ * Configures error chaining support
49
+ *
50
+ * See:
51
+ * - https://nodejs.org/en/blog/release/v16.9.0/#error-cause
52
+ * - https://github.com/microsoft/TypeScript/issues/45167
53
+ */
54
+ initCause() {
55
+ if (this.response instanceof Error) {
56
+ this.cause = this.response;
57
+ }
45
58
  }
46
59
  initMessage() {
47
60
  if ((0, shared_utils_1.isString)(this.response)) {
@@ -27,8 +27,10 @@ export interface HttpServer<TRequest = any, TResponse = any> {
27
27
  listen(port: number | string, hostname: string, callback?: () => void): any;
28
28
  reply(response: any, body: any, statusCode?: number): any;
29
29
  status(response: any, statusCode: number): any;
30
+ end(response: any, message?: string): any;
30
31
  render(response: any, view: string, options: any): any;
31
32
  redirect(response: any, statusCode: number, url: string): any;
33
+ isHeadersSent(response: any): boolean;
32
34
  setHeader(response: any, name: string, value: string): any;
33
35
  setErrorHandler?(handler: Function, prefix?: string): any;
34
36
  setNotFoundHandler?(handler: Function, prefix?: string): any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/common",
3
- "version": "9.0.0-next.1",
3
+ "version": "9.0.0-next.2",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@common)",
5
5
  "author": "Kamil Mysliwiec",
6
6
  "homepage": "https://nestjs.com",
@@ -0,0 +1,15 @@
1
+ import { FileValidator } from './file-validator.interface';
2
+ export declare type FileTypeValidatorOptions = {
3
+ fileType: string;
4
+ };
5
+ /**
6
+ * Defines the built-in FileType File Validator
7
+ *
8
+ * @see [File Validators](https://docs.nestjs.com/techniques/file-upload#validators)
9
+ *
10
+ * @publicApi
11
+ */
12
+ export declare class FileTypeValidator extends FileValidator<FileTypeValidatorOptions> {
13
+ buildErrorMessage(): string;
14
+ isValid(file: any): boolean;
15
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileTypeValidator = void 0;
4
+ const file_validator_interface_1 = require("./file-validator.interface");
5
+ /**
6
+ * Defines the built-in FileType File Validator
7
+ *
8
+ * @see [File Validators](https://docs.nestjs.com/techniques/file-upload#validators)
9
+ *
10
+ * @publicApi
11
+ */
12
+ class FileTypeValidator extends file_validator_interface_1.FileValidator {
13
+ buildErrorMessage() {
14
+ return `Validation failed (expected type is ${this.validationOptions.fileType})`;
15
+ }
16
+ isValid(file) {
17
+ if (!this.validationOptions) {
18
+ return true;
19
+ }
20
+ if (!file.mimetype) {
21
+ return false;
22
+ }
23
+ return file.mimetype.endsWith(this.validationOptions.fileType);
24
+ }
25
+ }
26
+ exports.FileTypeValidator = FileTypeValidator;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Interface describing FileValidators, which can be added to a {@link ParseFilePipe}.
3
+ */
4
+ export declare abstract class FileValidator<TValidationOptions = Record<string, any>> {
5
+ protected readonly validationOptions: TValidationOptions;
6
+ constructor(validationOptions: TValidationOptions);
7
+ /**
8
+ * Indicates if this file should be considered valid, according to the options passed in the constructor.
9
+ * @param file the file from the request object
10
+ */
11
+ abstract isValid(file?: any): boolean | Promise<boolean>;
12
+ /**
13
+ * Builds an error message in case the validation fails.
14
+ * @param file the file from the request object
15
+ */
16
+ abstract buildErrorMessage(file: any): string;
17
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileValidator = void 0;
4
+ /**
5
+ * Interface describing FileValidators, which can be added to a {@link ParseFilePipe}.
6
+ */
7
+ class FileValidator {
8
+ constructor(validationOptions) {
9
+ this.validationOptions = validationOptions;
10
+ }
11
+ }
12
+ exports.FileValidator = FileValidator;
@@ -0,0 +1,6 @@
1
+ export * from './file-type.validator';
2
+ export * from './file-validator.interface';
3
+ export * from './max-file-size.validator';
4
+ export * from './parse-file-options.interface';
5
+ export * from './parse-file.pipe';
6
+ export * from './parse-file-pipe.builder';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./file-type.validator"), exports);
5
+ tslib_1.__exportStar(require("./file-validator.interface"), exports);
6
+ tslib_1.__exportStar(require("./max-file-size.validator"), exports);
7
+ tslib_1.__exportStar(require("./parse-file-options.interface"), exports);
8
+ tslib_1.__exportStar(require("./parse-file.pipe"), exports);
9
+ tslib_1.__exportStar(require("./parse-file-pipe.builder"), exports);
@@ -0,0 +1,15 @@
1
+ import { FileValidator } from './file-validator.interface';
2
+ export declare type MaxFileSizeValidatorOptions = {
3
+ maxSize: number;
4
+ };
5
+ /**
6
+ * Defines the built-in MaxSize File Validator
7
+ *
8
+ * @see [File Validators](https://docs.nestjs.com/techniques/file-upload#validators)
9
+ *
10
+ * @publicApi
11
+ */
12
+ export declare class MaxFileSizeValidator extends FileValidator<MaxFileSizeValidatorOptions> {
13
+ buildErrorMessage(): string;
14
+ isValid(file: any): boolean;
15
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MaxFileSizeValidator = void 0;
4
+ const file_validator_interface_1 = require("./file-validator.interface");
5
+ /**
6
+ * Defines the built-in MaxSize File Validator
7
+ *
8
+ * @see [File Validators](https://docs.nestjs.com/techniques/file-upload#validators)
9
+ *
10
+ * @publicApi
11
+ */
12
+ class MaxFileSizeValidator extends file_validator_interface_1.FileValidator {
13
+ buildErrorMessage() {
14
+ return `Validation failed (expected size is less than ${this.validationOptions.maxSize})`;
15
+ }
16
+ isValid(file) {
17
+ if (!this.validationOptions) {
18
+ return true;
19
+ }
20
+ return file.size < this.validationOptions.maxSize;
21
+ }
22
+ }
23
+ exports.MaxFileSizeValidator = MaxFileSizeValidator;
@@ -0,0 +1,7 @@
1
+ import { ErrorHttpStatusCode } from '../../utils/http-error-by-code.util';
2
+ import { FileValidator } from './file-validator.interface';
3
+ export interface ParseFileOptions {
4
+ validators?: FileValidator[];
5
+ errorHttpStatusCode?: ErrorHttpStatusCode;
6
+ exceptionFactory?: (error: string) => any;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ import { FileTypeValidatorOptions } from './file-type.validator';
2
+ import { MaxFileSizeValidatorOptions } from './max-file-size.validator';
3
+ import { ParseFileOptions } from './parse-file-options.interface';
4
+ import { ParseFilePipe } from './parse-file.pipe';
5
+ export declare class ParseFilePipeBuilder {
6
+ private validators;
7
+ addMaxSizeValidator(options: MaxFileSizeValidatorOptions): this;
8
+ addFileTypeValidator(options: FileTypeValidatorOptions): this;
9
+ build(additionalOptions?: Omit<ParseFileOptions, 'validators'>): ParseFilePipe;
10
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ParseFilePipeBuilder = void 0;
4
+ const file_type_validator_1 = require("./file-type.validator");
5
+ const max_file_size_validator_1 = require("./max-file-size.validator");
6
+ const parse_file_pipe_1 = require("./parse-file.pipe");
7
+ class ParseFilePipeBuilder {
8
+ constructor() {
9
+ this.validators = [];
10
+ }
11
+ addMaxSizeValidator(options) {
12
+ this.validators.push(new max_file_size_validator_1.MaxFileSizeValidator(options));
13
+ return this;
14
+ }
15
+ addFileTypeValidator(options) {
16
+ this.validators.push(new file_type_validator_1.FileTypeValidator(options));
17
+ return this;
18
+ }
19
+ build(additionalOptions) {
20
+ const parseFilePipe = new parse_file_pipe_1.ParseFilePipe(Object.assign(Object.assign({}, additionalOptions), { validators: this.validators }));
21
+ this.validators = [];
22
+ return parseFilePipe;
23
+ }
24
+ }
25
+ exports.ParseFilePipeBuilder = ParseFilePipeBuilder;
@@ -0,0 +1,25 @@
1
+ import { PipeTransform } from '../../interfaces/features/pipe-transform.interface';
2
+ import { ParseFileOptions } from './parse-file-options.interface';
3
+ import { FileValidator } from './file-validator.interface';
4
+ /**
5
+ * Defines the built-in ParseFile Pipe. This pipe can be used to validate incoming files
6
+ * with `@UploadedFile()` decorator. You can use either other specific built-in validators
7
+ * or provide one of your own, simply implementing it through {@link FileValidator}
8
+ * interface and adding it to ParseFilePipe's constructor.
9
+ *
10
+ * @see [Built-in Pipes](https://docs.nestjs.com/pipes#built-in-pipes)
11
+ *
12
+ * @publicApi
13
+ */
14
+ export declare class ParseFilePipe implements PipeTransform<any> {
15
+ protected exceptionFactory: (error: string) => any;
16
+ private readonly validators;
17
+ constructor(options?: ParseFileOptions);
18
+ transform(value: any): Promise<any>;
19
+ protected validate(file: any): Promise<any>;
20
+ private validateOrThrow;
21
+ /**
22
+ * @returns list of validators used in this pipe.
23
+ */
24
+ getValidators(): FileValidator<Record<string, any>>[];
25
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ParseFilePipe = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("../../decorators/core");
6
+ const enums_1 = require("../../enums");
7
+ const http_error_by_code_util_1 = require("../../utils/http-error-by-code.util");
8
+ /**
9
+ * Defines the built-in ParseFile Pipe. This pipe can be used to validate incoming files
10
+ * with `@UploadedFile()` decorator. You can use either other specific built-in validators
11
+ * or provide one of your own, simply implementing it through {@link FileValidator}
12
+ * interface and adding it to ParseFilePipe's constructor.
13
+ *
14
+ * @see [Built-in Pipes](https://docs.nestjs.com/pipes#built-in-pipes)
15
+ *
16
+ * @publicApi
17
+ */
18
+ let ParseFilePipe = class ParseFilePipe {
19
+ constructor(options = {}) {
20
+ const { exceptionFactory, errorHttpStatusCode = enums_1.HttpStatus.BAD_REQUEST, validators = [], } = options;
21
+ this.exceptionFactory =
22
+ exceptionFactory ||
23
+ (error => new http_error_by_code_util_1.HttpErrorByCode[errorHttpStatusCode](error));
24
+ this.validators = validators;
25
+ }
26
+ async transform(value) {
27
+ if (this.validators.length) {
28
+ await this.validate(value);
29
+ }
30
+ return value;
31
+ }
32
+ async validate(file) {
33
+ for (const validator of this.validators) {
34
+ await this.validateOrThrow(file, validator);
35
+ }
36
+ return file;
37
+ }
38
+ async validateOrThrow(file, validator) {
39
+ const isValid = await validator.isValid(file);
40
+ if (!isValid) {
41
+ const errorMessage = validator.buildErrorMessage(file);
42
+ throw this.exceptionFactory(errorMessage);
43
+ }
44
+ }
45
+ /**
46
+ * @returns list of validators used in this pipe.
47
+ */
48
+ getValidators() {
49
+ return this.validators;
50
+ }
51
+ };
52
+ ParseFilePipe = tslib_1.__decorate([
53
+ (0, core_1.Injectable)(),
54
+ tslib_1.__param(0, (0, core_1.Optional)()),
55
+ tslib_1.__metadata("design:paramtypes", [Object])
56
+ ], ParseFilePipe);
57
+ exports.ParseFilePipe = ParseFilePipe;
package/pipes/index.d.ts CHANGED
@@ -6,3 +6,4 @@ export * from './parse-float.pipe';
6
6
  export * from './parse-enum.pipe';
7
7
  export * from './parse-uuid.pipe';
8
8
  export * from './validation.pipe';
9
+ export * from './file';
package/pipes/index.js CHANGED
@@ -9,3 +9,4 @@ tslib_1.__exportStar(require("./parse-float.pipe"), exports);
9
9
  tslib_1.__exportStar(require("./parse-enum.pipe"), exports);
10
10
  tslib_1.__exportStar(require("./parse-uuid.pipe"), exports);
11
11
  tslib_1.__exportStar(require("./validation.pipe"), exports);
12
+ tslib_1.__exportStar(require("./file"), exports);
@@ -34,7 +34,7 @@ export declare class ValidationPipe implements PipeTransform<any> {
34
34
  protected toValidate(metadata: ArgumentMetadata): boolean;
35
35
  protected transformPrimitive(value: any, metadata: ArgumentMetadata): any;
36
36
  protected toEmptyIfNil<T = any, R = any>(value: T): R | {};
37
- protected stripProtoKeys(value: Record<string, any>): void;
37
+ protected stripProtoKeys(value: any): void;
38
38
  protected isPrimitive(value: unknown): boolean;
39
39
  protected validate(object: object, validatorOptions?: ValidatorOptions): Promise<ValidationError[]> | ValidationError[];
40
40
  protected flattenValidationErrors(validationErrors: ValidationError[]): string[];
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ValidationPipe = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const iterare_1 = require("iterare");
6
+ const util_1 = require("util");
6
7
  const decorators_1 = require("../decorators");
7
8
  const core_1 = require("../decorators/core");
8
9
  const http_status_enum_1 = require("../enums/http-status.enum");
@@ -118,11 +119,21 @@ let ValidationPipe = class ValidationPipe {
118
119
  return (0, shared_utils_1.isNil)(value) ? {} : value;
119
120
  }
120
121
  stripProtoKeys(value) {
122
+ if (value == null ||
123
+ typeof value !== 'object' ||
124
+ util_1.types.isTypedArray(value)) {
125
+ return;
126
+ }
127
+ if (Array.isArray(value)) {
128
+ for (const v of value) {
129
+ this.stripProtoKeys(v);
130
+ }
131
+ return;
132
+ }
121
133
  delete value.__proto__;
122
- const keys = Object.keys(value);
123
- (0, iterare_1.iterate)(keys)
124
- .filter(key => (0, shared_utils_1.isObject)(value[key]) && value[key])
125
- .forEach(key => this.stripProtoKeys(value[key]));
134
+ for (const key in value) {
135
+ this.stripProtoKeys(value[key]);
136
+ }
126
137
  }
127
138
  isPrimitive(value) {
128
139
  return ['number', 'boolean', 'string'].includes(typeof value);
@@ -1,4 +1,5 @@
1
1
  export declare const clc: {
2
+ bold: (text: string) => string;
2
3
  green: (text: string) => string;
3
4
  yellow: (text: string) => string;
4
5
  red: (text: string) => string;
@@ -4,6 +4,7 @@ exports.yellow = exports.clc = void 0;
4
4
  const isColorAllowed = () => !process.env.NO_COLOR;
5
5
  const colorIfAllowed = (colorFn) => (text) => isColorAllowed() ? colorFn(text) : text;
6
6
  exports.clc = {
7
+ bold: colorIfAllowed((text) => `\x1B[1m${text}\x1B[0m`),
7
8
  green: colorIfAllowed((text) => `\x1B[32m${text}\x1B[39m`),
8
9
  yellow: colorIfAllowed((text) => `\x1B[33m${text}\x1B[39m`),
9
10
  red: colorIfAllowed((text) => `\x1B[31m${text}\x1B[39m`),