@ts-typed/nestjs 0.0.1 → 0.1.1
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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ All notable changes to `@ts-typed/nestjs` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.1] - 2026-10-17
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `StrictTypeErrorFilter` kept returning HTTP 400 for a violation on a plain local variable (e.g. `const entity = await repo.findOneBy(...)` reading corrupted data back from a database) because the value flowed through an `initialize`/`set` operation, not `return`/`resolve`. A local variable is never the client-facing surface of a request — client input only ever reaches a protected contract through a `parameter` or a `property` (a DTO's own fields) — so a violation whose `contractKind` is `variable` now also maps to HTTP 500, regardless of its `operation`.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Depends on `@ts-typed/compiler@0.1.1`.
|
|
16
|
+
|
|
17
|
+
## [0.1.0] - 2026-10-17
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- `StrictTypeErrorFilter` returned HTTP 400 for every `StrictTypeError`, including one raised while validating a function or method's own return value (for example, a mapper reading a corrupted row out of the database) — a server-side failure, not a bad request. A violation whose `operation` is `return` or `resolve` now maps to HTTP 500; every other operation (`argument`, `set`, `initialize`, …) keeps the existing 400.
|
|
22
|
+
- The package's `exports` map did not expose `./package.json`, breaking `require.resolve('@ts-typed/nestjs/package.json')` and similar version-probing patterns.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Depends on `@ts-typed/compiler@0.1.0`, whose changelog covers the coverage gaps (class methods/constructors, decorated fields, `Date`) that this package's own tests exercise against a real NestJS app.
|
|
27
|
+
|
|
7
28
|
## [0.0.1] - 2026-10-16
|
|
8
29
|
|
|
9
30
|
Initial release.
|
|
@@ -2,13 +2,13 @@ import type { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
|
|
|
2
2
|
import { StrictTypeError } from '@ts-typed/compiler';
|
|
3
3
|
/**
|
|
4
4
|
* Translates a `StrictTypeError` thrown by instrumented code (a DTO/provider
|
|
5
|
-
* field failing validation at a protected boundary) into
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* field failing validation at a protected boundary) into an HTTP response,
|
|
6
|
+
* using `StrictTypeError#toJSON()`'s already-safe payload (no raw received
|
|
7
|
+
* value, no stack). Register it the same way as any other Nest exception
|
|
8
|
+
* filter (`@UseFilters(StrictTypeErrorFilter)` or as a global `APP_FILTER`
|
|
9
|
+
* provider); it does not replace Nest's own validation pipes or instantiate
|
|
10
|
+
* DTOs — it only reacts to an error ts-typed's own instrumented code already
|
|
11
|
+
* threw.
|
|
12
12
|
*/
|
|
13
13
|
export declare class StrictTypeErrorFilter implements ExceptionFilter {
|
|
14
14
|
catch(exception: StrictTypeError, host: ArgumentsHost): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strict-type-error.filter.d.ts","sourceRoot":"","sources":["../src/strict-type-error.filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"strict-type-error.filter.d.ts","sourceRoot":"","sources":["../src/strict-type-error.filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA+BrD;;;;;;;;;GASG;AACH,qBACa,qBAAsB,YAAW,eAAe;IACpD,KAAK,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;CAapE"}
|
|
@@ -9,24 +9,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.StrictTypeErrorFilter = void 0;
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
11
|
const compiler_1 = require("@ts-typed/compiler");
|
|
12
|
+
/**
|
|
13
|
+
* A `return`/`resolve` violation means the function or method's OWN body
|
|
14
|
+
* produced a value that fails its declared return type — e.g. a mapper
|
|
15
|
+
* reading a corrupted row out of the database. The client did nothing wrong
|
|
16
|
+
* at that boundary, so it is a server-side failure (500), not a bad request
|
|
17
|
+
* (400). Every other operation (`argument`, `set`, `initialize`, …) reflects
|
|
18
|
+
* a value that came from outside the function at that exact validation
|
|
19
|
+
* point — closer to client-controlled input — and keeps the 400 default.
|
|
20
|
+
*/
|
|
21
|
+
const SERVER_FAULT_OPERATIONS = new Set(['return', 'resolve']);
|
|
22
|
+
/**
|
|
23
|
+
* A plain local variable (`const entity = await repo.findOneBy(...)`) is
|
|
24
|
+
* never the client-facing surface of a request: client input only ever
|
|
25
|
+
* reaches a protected contract through a `parameter` (`@Body()`/`@Param()`
|
|
26
|
+
* decorated arguments, which use the `argument` operation, never
|
|
27
|
+
* `variable`) or a `property` (a DTO's own fields). A violation whose
|
|
28
|
+
* `contractKind` is `variable` is therefore always a server-side data
|
|
29
|
+
* problem — typically corrupted data read back from a database — even
|
|
30
|
+
* though its `operation` is `initialize`/`set`, which otherwise means
|
|
31
|
+
* "value came from outside this function" and defaults to 400.
|
|
32
|
+
*/
|
|
33
|
+
const SERVER_FAULT_CONTRACT_KINDS = new Set(['variable']);
|
|
12
34
|
/**
|
|
13
35
|
* Translates a `StrictTypeError` thrown by instrumented code (a DTO/provider
|
|
14
|
-
* field failing validation at a protected boundary) into
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
36
|
+
* field failing validation at a protected boundary) into an HTTP response,
|
|
37
|
+
* using `StrictTypeError#toJSON()`'s already-safe payload (no raw received
|
|
38
|
+
* value, no stack). Register it the same way as any other Nest exception
|
|
39
|
+
* filter (`@UseFilters(StrictTypeErrorFilter)` or as a global `APP_FILTER`
|
|
40
|
+
* provider); it does not replace Nest's own validation pipes or instantiate
|
|
41
|
+
* DTOs — it only reacts to an error ts-typed's own instrumented code already
|
|
42
|
+
* threw.
|
|
21
43
|
*/
|
|
22
44
|
let StrictTypeErrorFilter = class StrictTypeErrorFilter {
|
|
23
45
|
catch(exception, host) {
|
|
24
46
|
const response = host.switchToHttp().getResponse();
|
|
47
|
+
const isServerFault = SERVER_FAULT_OPERATIONS.has(exception.operation) ||
|
|
48
|
+
SERVER_FAULT_CONTRACT_KINDS.has(exception.contractKind);
|
|
49
|
+
const status = isServerFault ? common_1.HttpStatus.INTERNAL_SERVER_ERROR : common_1.HttpStatus.BAD_REQUEST;
|
|
25
50
|
const httpException = new common_1.HttpException({
|
|
26
|
-
statusCode:
|
|
51
|
+
statusCode: status,
|
|
27
52
|
message: exception.message,
|
|
28
53
|
...exception.toJSON(),
|
|
29
|
-
},
|
|
54
|
+
}, status);
|
|
30
55
|
response.status(httpException.getStatus()).json(httpException.getResponse());
|
|
31
56
|
}
|
|
32
57
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strict-type-error.filter.js","sourceRoot":"","sources":["../src/strict-type-error.filter.ts"],"names":[],"mappings":";;;;;;;;;AACA,2CAAkE;AAClE,iDAAqD;AAOrD;;;;;;;;;GASG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IACzB,KAAK,CAAC,SAA0B,EAAE,IAAmB;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,WAAW,EAAuB,CAAC;QACxE,MAAM,aAAa,GAAG,
|
|
1
|
+
{"version":3,"file":"strict-type-error.filter.js","sourceRoot":"","sources":["../src/strict-type-error.filter.ts"],"names":[],"mappings":";;;;;;;;;AACA,2CAAkE;AAClE,iDAAqD;AAOrD;;;;;;;;GAQG;AACH,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAEpF;;;;;;;;;;GAUG;AACH,MAAM,2BAA2B,GAAwB,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AAE/E;;;;;;;;;GASG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IACzB,KAAK,CAAC,SAA0B,EAAE,IAAmB;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,WAAW,EAAuB,CAAC;QACxE,MAAM,aAAa,GACjB,uBAAuB,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;YAChD,2BAA2B,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,mBAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,mBAAU,CAAC,WAAW,CAAC;QACzF,MAAM,aAAa,GAAG,IAAI,sBAAa,CAAC;YACtC,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,GAAG,SAAS,CAAC,MAAM,EAAE;SACtB,EAAE,MAAM,CAAC,CAAC;QACX,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/E,CAAC;CACF,CAAA;AAdY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,cAAK,EAAC,0BAAe,CAAC;GACV,qBAAqB,CAcjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-typed/nestjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"require": "./dist/index.js",
|
|
19
19
|
"default": "./dist/index.js"
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
21
22
|
},
|
|
22
23
|
"files": [
|
|
23
24
|
"dist",
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
"test": "npm run build && node --test --test-concurrency=1"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"@ts-typed/compiler": "0.
|
|
36
|
+
"@ts-typed/compiler": "0.1.1"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
39
|
"@nestjs/common": ">=10 <13",
|