@leo-h/create-nodejs-app 1.0.12 → 1.0.14
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/dist/package.json.js +1 -1
- package/package.json +1 -1
- package/templates/clean/build.config.ts +1 -0
- package/templates/fastify/build.config.ts +1 -0
- package/templates/fastify/package.json +3 -1
- package/templates/fastify/pnpm-lock.yaml +107 -0
- package/templates/nest/package.json +4 -2
- package/templates/nest/pnpm-lock.yaml +147 -18
- package/templates/nest/src/core/errors/validation.error.ts +12 -0
- package/templates/nest/src/infra/http/errors/filters/all-exception.filter.ts +31 -0
- package/templates/nest/src/infra/http/errors/filters/domain-exception.filter.ts +39 -0
- package/templates/nest/src/infra/http/errors/internal-server.error.ts +15 -0
- package/templates/nest/src/infra/http/http.module.ts +4 -4
- package/templates/nest/src/infra/http/middlewares/upload-interceptor.ts +53 -16
- package/templates/nest/src/infra/http/middlewares/zod-schema-pipe.ts +24 -11
- package/templates/nest/src/infra/http/middlewares/zod-validation-pipe.ts +4 -4
- package/templates/nest/src/infra/presenters/error.presenter.ts +2 -1
- package/templates/nest/src/core/errors/errors.ts +0 -9
- package/templates/nest/src/infra/http/filters/domain-exception.filter.ts +0 -53
- package/templates/nest/src/infra/http/filters/http-exception.filter.ts +0 -26
package/dist/package.json.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:!0});const name="@leo-h/create-nodejs-app",version="1.0.
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0});const name="@leo-h/create-nodejs-app",version="1.0.14",packageManager="pnpm@9.1.1",author="Leonardo Henrique <leonardo0507.business@gmail.com>",description="Create a modern Node.js app with TypeScript using one command.",license="MIT",keywords=["node","node.js","typescript"],bin={"create-nodejs-app":"./dist/index.js"},files=["./dist","./templates"],repository={type:"git",url:"https://github.com/Leo-Henrique/create-nodejs-app"},scripts={prepare:"husky",start:"node ./dist/index.js","start:dev":"tsx ./src/index.ts","start:dev:watch":"tsx watch ./src/index.ts",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts --max-warnings 0 --cache","lint:fix":"pnpm lint --fix",format:"prettier . --write --cache","test:unit":"vitest run","test:unit:watch":"vitest","test:e2e":"vitest run --config ./vitest.config.e2e.mts","test:e2e:watch":"vitest --config ./vitest.config.e2e.mts","test:coverage":"vitest run --coverage.enabled=true",template:"tsx ./scripts/template-cli.ts",prebuild:"rimraf ./dist",build:"unbuild",prepublishOnly:"pnpm build"},dependencies={commander:"12.1.0",picocolors:"1.0.1",prompts:"2.4.2","validate-npm-package-name":"5.0.1",zod:"3.23.8"},devDependencies={"@faker-js/faker":"8.4.1","@types/node":"20.12.12","@types/prompts":"2.4.9","@types/validate-npm-package-name":"4.0.2","@typescript-eslint/eslint-plugin":"7.10.0","@typescript-eslint/parser":"7.10.0","conventional-changelog-conventionalcommits":"8.0.0",eslint:"8.57.0","eslint-config-prettier":"9.1.0","eslint-plugin-vitest":"0.4.0",husky:"9.0.11","lint-staged":"15.2.2","npm-run-all":"4.1.5",prettier:"3.2.5",rimraf:"5.0.7",tsx:"4.10.5",typescript:"5.4.5",unbuild:"2.0.0","vite-tsconfig-paths":"4.3.2",vitest:"1.6.0"},d={name,version,packageManager,author,description,license,keywords,bin,files,repository,scripts,dependencies,devDependencies};exports.author=author;exports.bin=bin;exports.default=d;exports.dependencies=dependencies;exports.description=description;exports.devDependencies=devDependencies;exports.files=files;exports.keywords=keywords;exports.license=license;exports.name=name;exports.packageManager=packageManager;exports.repository=repository;exports.scripts=scripts;exports.version=version;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@leo-h/create-nodejs-app",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.14",
|
4
4
|
"packageManager": "pnpm@9.1.1",
|
5
5
|
"author": "Leonardo Henrique <leonardo0507.business@gmail.com>",
|
6
6
|
"description": "Create a modern Node.js app with TypeScript using one command.",
|
@@ -12,9 +12,10 @@
|
|
12
12
|
"format": "prettier . --write --cache",
|
13
13
|
"test:unit": "vitest run",
|
14
14
|
"test:unit:watch": "vitest",
|
15
|
+
"test:unit:coverage": "vitest run --coverage.enabled=true",
|
15
16
|
"test:e2e": "vitest run --config ./vitest.config.e2e.mts",
|
16
17
|
"test:e2e:watch": "vitest --config ./vitest.config.e2e.mts",
|
17
|
-
"test:coverage": "vitest run --coverage.enabled=true",
|
18
|
+
"test:e2e:coverage": "vitest run --config ./vitest.config.e2e.mts --coverage.enabled=true",
|
18
19
|
"prebuild": "rimraf ./dist",
|
19
20
|
"build": "unbuild"
|
20
21
|
},
|
@@ -39,6 +40,7 @@
|
|
39
40
|
"@types/supertest": "6.0.2",
|
40
41
|
"@typescript-eslint/eslint-plugin": "7.10.0",
|
41
42
|
"@typescript-eslint/parser": "7.10.0",
|
43
|
+
"@vitest/coverage-v8": "1.6.0",
|
42
44
|
"eslint": "8.57.0",
|
43
45
|
"eslint-config-prettier": "9.1.0",
|
44
46
|
"eslint-plugin-vitest": "0.4.0",
|
@@ -63,6 +63,9 @@ importers:
|
|
63
63
|
'@typescript-eslint/parser':
|
64
64
|
specifier: 7.10.0
|
65
65
|
version: 7.10.0(eslint@8.57.0)(typescript@5.4.5)
|
66
|
+
'@vitest/coverage-v8':
|
67
|
+
specifier: 1.6.0
|
68
|
+
version: 1.6.0(vitest@1.6.0(@types/node@20.12.12))
|
66
69
|
eslint:
|
67
70
|
specifier: 8.57.0
|
68
71
|
version: 8.57.0
|
@@ -203,6 +206,9 @@ packages:
|
|
203
206
|
resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==}
|
204
207
|
engines: {node: '>=6.9.0'}
|
205
208
|
|
209
|
+
'@bcoe/v8-coverage@0.2.3':
|
210
|
+
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
211
|
+
|
206
212
|
'@esbuild/aix-ppc64@0.19.12':
|
207
213
|
resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
|
208
214
|
engines: {node: '>=12'}
|
@@ -556,6 +562,10 @@ packages:
|
|
556
562
|
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
557
563
|
engines: {node: '>=12'}
|
558
564
|
|
565
|
+
'@istanbuljs/schema@0.1.3':
|
566
|
+
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
|
567
|
+
engines: {node: '>=8'}
|
568
|
+
|
559
569
|
'@jest/schemas@29.6.3':
|
560
570
|
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
|
561
571
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
@@ -855,6 +865,11 @@ packages:
|
|
855
865
|
'@ungap/structured-clone@1.2.0':
|
856
866
|
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
857
867
|
|
868
|
+
'@vitest/coverage-v8@1.6.0':
|
869
|
+
resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==}
|
870
|
+
peerDependencies:
|
871
|
+
vitest: 1.6.0
|
872
|
+
|
858
873
|
'@vitest/expect@1.6.0':
|
859
874
|
resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==}
|
860
875
|
|
@@ -1591,6 +1606,9 @@ packages:
|
|
1591
1606
|
hookable@5.5.3:
|
1592
1607
|
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
1593
1608
|
|
1609
|
+
html-escaper@2.0.2:
|
1610
|
+
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
1611
|
+
|
1594
1612
|
http-errors@2.0.0:
|
1595
1613
|
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
1596
1614
|
engines: {node: '>= 0.8'}
|
@@ -1678,6 +1696,22 @@ packages:
|
|
1678
1696
|
isexe@2.0.0:
|
1679
1697
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
1680
1698
|
|
1699
|
+
istanbul-lib-coverage@3.2.2:
|
1700
|
+
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
|
1701
|
+
engines: {node: '>=8'}
|
1702
|
+
|
1703
|
+
istanbul-lib-report@3.0.1:
|
1704
|
+
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
|
1705
|
+
engines: {node: '>=10'}
|
1706
|
+
|
1707
|
+
istanbul-lib-source-maps@5.0.6:
|
1708
|
+
resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==}
|
1709
|
+
engines: {node: '>=10'}
|
1710
|
+
|
1711
|
+
istanbul-reports@3.1.7:
|
1712
|
+
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
|
1713
|
+
engines: {node: '>=8'}
|
1714
|
+
|
1681
1715
|
jackspeak@3.4.0:
|
1682
1716
|
resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
|
1683
1717
|
engines: {node: '>=14'}
|
@@ -1785,6 +1819,13 @@ packages:
|
|
1785
1819
|
magic-string@0.30.10:
|
1786
1820
|
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
|
1787
1821
|
|
1822
|
+
magicast@0.3.4:
|
1823
|
+
resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==}
|
1824
|
+
|
1825
|
+
make-dir@4.0.0:
|
1826
|
+
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
1827
|
+
engines: {node: '>=10'}
|
1828
|
+
|
1788
1829
|
mdn-data@2.0.28:
|
1789
1830
|
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
1790
1831
|
|
@@ -2483,6 +2524,10 @@ packages:
|
|
2483
2524
|
engines: {node: '>=14.0.0'}
|
2484
2525
|
hasBin: true
|
2485
2526
|
|
2527
|
+
test-exclude@6.0.0:
|
2528
|
+
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
|
2529
|
+
engines: {node: '>=8'}
|
2530
|
+
|
2486
2531
|
text-decoding@1.0.0:
|
2487
2532
|
resolution: {integrity: sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==}
|
2488
2533
|
|
@@ -2878,6 +2923,8 @@ snapshots:
|
|
2878
2923
|
'@babel/helper-validator-identifier': 7.24.7
|
2879
2924
|
to-fast-properties: 2.0.0
|
2880
2925
|
|
2926
|
+
'@bcoe/v8-coverage@0.2.3': {}
|
2927
|
+
|
2881
2928
|
'@esbuild/aix-ppc64@0.19.12':
|
2882
2929
|
optional: true
|
2883
2930
|
|
@@ -3129,6 +3176,8 @@ snapshots:
|
|
3129
3176
|
wrap-ansi: 8.1.0
|
3130
3177
|
wrap-ansi-cjs: wrap-ansi@7.0.0
|
3131
3178
|
|
3179
|
+
'@istanbuljs/schema@0.1.3': {}
|
3180
|
+
|
3132
3181
|
'@jest/schemas@29.6.3':
|
3133
3182
|
dependencies:
|
3134
3183
|
'@sinclair/typebox': 0.27.8
|
@@ -3416,6 +3465,25 @@ snapshots:
|
|
3416
3465
|
|
3417
3466
|
'@ungap/structured-clone@1.2.0': {}
|
3418
3467
|
|
3468
|
+
'@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.12.12))':
|
3469
|
+
dependencies:
|
3470
|
+
'@ampproject/remapping': 2.3.0
|
3471
|
+
'@bcoe/v8-coverage': 0.2.3
|
3472
|
+
debug: 4.3.5
|
3473
|
+
istanbul-lib-coverage: 3.2.2
|
3474
|
+
istanbul-lib-report: 3.0.1
|
3475
|
+
istanbul-lib-source-maps: 5.0.6
|
3476
|
+
istanbul-reports: 3.1.7
|
3477
|
+
magic-string: 0.30.10
|
3478
|
+
magicast: 0.3.4
|
3479
|
+
picocolors: 1.0.1
|
3480
|
+
std-env: 3.7.0
|
3481
|
+
strip-literal: 2.1.0
|
3482
|
+
test-exclude: 6.0.0
|
3483
|
+
vitest: 1.6.0(@types/node@20.12.12)
|
3484
|
+
transitivePeerDependencies:
|
3485
|
+
- supports-color
|
3486
|
+
|
3419
3487
|
'@vitest/expect@1.6.0':
|
3420
3488
|
dependencies:
|
3421
3489
|
'@vitest/spy': 1.6.0
|
@@ -4263,6 +4331,8 @@ snapshots:
|
|
4263
4331
|
|
4264
4332
|
hookable@5.5.3: {}
|
4265
4333
|
|
4334
|
+
html-escaper@2.0.2: {}
|
4335
|
+
|
4266
4336
|
http-errors@2.0.0:
|
4267
4337
|
dependencies:
|
4268
4338
|
depd: 2.0.0
|
@@ -4331,6 +4401,27 @@ snapshots:
|
|
4331
4401
|
|
4332
4402
|
isexe@2.0.0: {}
|
4333
4403
|
|
4404
|
+
istanbul-lib-coverage@3.2.2: {}
|
4405
|
+
|
4406
|
+
istanbul-lib-report@3.0.1:
|
4407
|
+
dependencies:
|
4408
|
+
istanbul-lib-coverage: 3.2.2
|
4409
|
+
make-dir: 4.0.0
|
4410
|
+
supports-color: 7.2.0
|
4411
|
+
|
4412
|
+
istanbul-lib-source-maps@5.0.6:
|
4413
|
+
dependencies:
|
4414
|
+
'@jridgewell/trace-mapping': 0.3.25
|
4415
|
+
debug: 4.3.5
|
4416
|
+
istanbul-lib-coverage: 3.2.2
|
4417
|
+
transitivePeerDependencies:
|
4418
|
+
- supports-color
|
4419
|
+
|
4420
|
+
istanbul-reports@3.1.7:
|
4421
|
+
dependencies:
|
4422
|
+
html-escaper: 2.0.2
|
4423
|
+
istanbul-lib-report: 3.0.1
|
4424
|
+
|
4334
4425
|
jackspeak@3.4.0:
|
4335
4426
|
dependencies:
|
4336
4427
|
'@isaacs/cliui': 8.0.2
|
@@ -4455,6 +4546,16 @@ snapshots:
|
|
4455
4546
|
dependencies:
|
4456
4547
|
'@jridgewell/sourcemap-codec': 1.4.15
|
4457
4548
|
|
4549
|
+
magicast@0.3.4:
|
4550
|
+
dependencies:
|
4551
|
+
'@babel/parser': 7.24.7
|
4552
|
+
'@babel/types': 7.24.7
|
4553
|
+
source-map-js: 1.2.0
|
4554
|
+
|
4555
|
+
make-dir@4.0.0:
|
4556
|
+
dependencies:
|
4557
|
+
semver: 7.6.2
|
4558
|
+
|
4458
4559
|
mdn-data@2.0.28: {}
|
4459
4560
|
|
4460
4561
|
mdn-data@2.0.30: {}
|
@@ -5108,6 +5209,12 @@ snapshots:
|
|
5108
5209
|
csso: 5.0.5
|
5109
5210
|
picocolors: 1.0.1
|
5110
5211
|
|
5212
|
+
test-exclude@6.0.0:
|
5213
|
+
dependencies:
|
5214
|
+
'@istanbuljs/schema': 0.1.3
|
5215
|
+
glob: 7.2.3
|
5216
|
+
minimatch: 3.1.2
|
5217
|
+
|
5111
5218
|
text-decoding@1.0.0: {}
|
5112
5219
|
|
5113
5220
|
text-table@0.2.0: {}
|
@@ -12,13 +12,13 @@
|
|
12
12
|
"format": "prettier . --write --cache",
|
13
13
|
"test:unit": "vitest run",
|
14
14
|
"test:unit:watch": "vitest",
|
15
|
+
"test:unit:coverage": "vitest run --coverage.enabled=true",
|
15
16
|
"test:e2e": "vitest run --config ./vitest.config.e2e.mts",
|
16
17
|
"test:e2e:watch": "vitest --config ./vitest.config.e2e.mts",
|
17
|
-
"test:coverage": "vitest run --coverage.enabled=true",
|
18
|
+
"test:e2e:coverage": "vitest run --config ./vitest.config.e2e.mts --coverage.enabled=true",
|
18
19
|
"build": "nest build"
|
19
20
|
},
|
20
21
|
"dependencies": {
|
21
|
-
"@anatine/zod-nestjs": "2.0.9",
|
22
22
|
"@anatine/zod-openapi": "2.2.6",
|
23
23
|
"@fastify/static": "7.0.4",
|
24
24
|
"@nestjs/common": "10.3.10",
|
@@ -30,6 +30,7 @@
|
|
30
30
|
"fastify-multer": "2.0.3",
|
31
31
|
"mime-types": "2.1.35",
|
32
32
|
"pretty-bytes": "5.6.0",
|
33
|
+
"rxjs": "7.8.1",
|
33
34
|
"zod": "3.23.8"
|
34
35
|
},
|
35
36
|
"devDependencies": {
|
@@ -44,6 +45,7 @@
|
|
44
45
|
"@types/supertest": "6.0.2",
|
45
46
|
"@typescript-eslint/eslint-plugin": "7.10.0",
|
46
47
|
"@typescript-eslint/parser": "7.10.0",
|
48
|
+
"@vitest/coverage-v8": "1.6.0",
|
47
49
|
"eslint": "8.57.0",
|
48
50
|
"eslint-config-prettier": "9.1.0",
|
49
51
|
"eslint-plugin-vitest": "0.4.0",
|
@@ -8,9 +8,6 @@ importers:
|
|
8
8
|
|
9
9
|
.:
|
10
10
|
dependencies:
|
11
|
-
'@anatine/zod-nestjs':
|
12
|
-
specifier: 2.0.9
|
13
|
-
version: 2.0.9(@anatine/zod-openapi@2.2.6(openapi3-ts@4.3.3)(zod@3.23.8))(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/swagger@7.4.0(@fastify/static@7.0.4)(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2))(openapi3-ts@4.3.3)(zod@3.23.8)
|
14
11
|
'@anatine/zod-openapi':
|
15
12
|
specifier: 2.2.6
|
16
13
|
version: 2.2.6(openapi3-ts@4.3.3)(zod@3.23.8)
|
@@ -44,6 +41,9 @@ importers:
|
|
44
41
|
pretty-bytes:
|
45
42
|
specifier: 5.6.0
|
46
43
|
version: 5.6.0
|
44
|
+
rxjs:
|
45
|
+
specifier: 7.8.1
|
46
|
+
version: 7.8.1
|
47
47
|
zod:
|
48
48
|
specifier: 3.23.8
|
49
49
|
version: 3.23.8
|
@@ -81,6 +81,9 @@ importers:
|
|
81
81
|
'@typescript-eslint/parser':
|
82
82
|
specifier: 7.10.0
|
83
83
|
version: 7.10.0(eslint@8.57.0)(typescript@5.4.5)
|
84
|
+
'@vitest/coverage-v8':
|
85
|
+
specifier: 1.6.0
|
86
|
+
version: 1.6.0(vitest@1.6.0(@types/node@20.12.12)(terser@5.31.3))
|
84
87
|
eslint:
|
85
88
|
specifier: 8.57.0
|
86
89
|
version: 8.57.0
|
@@ -117,14 +120,9 @@ importers:
|
|
117
120
|
|
118
121
|
packages:
|
119
122
|
|
120
|
-
'@
|
121
|
-
resolution: {integrity: sha512-
|
122
|
-
|
123
|
-
'@anatine/zod-openapi': ^2.0.1
|
124
|
-
'@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
|
125
|
-
'@nestjs/swagger': ^6.0.0 || ^7.0.0
|
126
|
-
openapi3-ts: ^4.1.2
|
127
|
-
zod: ^3.20.0
|
123
|
+
'@ampproject/remapping@2.3.0':
|
124
|
+
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
125
|
+
engines: {node: '>=6.0.0'}
|
128
126
|
|
129
127
|
'@anatine/zod-openapi@2.2.6':
|
130
128
|
resolution: {integrity: sha512-Z5sr2Nq2xifEpPbPdUcvyl776LY652oR3VHMV++WFSmRrRL8RDP2XTkbuGn+vgfVNOD7UrndYwCWnxaiw7IZog==}
|
@@ -154,6 +152,10 @@ packages:
|
|
154
152
|
resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
|
155
153
|
engines: {node: '>=6.9.0'}
|
156
154
|
|
155
|
+
'@babel/helper-string-parser@7.24.8':
|
156
|
+
resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==}
|
157
|
+
engines: {node: '>=6.9.0'}
|
158
|
+
|
157
159
|
'@babel/helper-validator-identifier@7.24.7':
|
158
160
|
resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
|
159
161
|
engines: {node: '>=6.9.0'}
|
@@ -162,6 +164,18 @@ packages:
|
|
162
164
|
resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
|
163
165
|
engines: {node: '>=6.9.0'}
|
164
166
|
|
167
|
+
'@babel/parser@7.25.4':
|
168
|
+
resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==}
|
169
|
+
engines: {node: '>=6.0.0'}
|
170
|
+
hasBin: true
|
171
|
+
|
172
|
+
'@babel/types@7.25.4':
|
173
|
+
resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==}
|
174
|
+
engines: {node: '>=6.9.0'}
|
175
|
+
|
176
|
+
'@bcoe/v8-coverage@0.2.3':
|
177
|
+
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
178
|
+
|
165
179
|
'@colors/colors@1.5.0':
|
166
180
|
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
167
181
|
engines: {node: '>=0.1.90'}
|
@@ -378,6 +392,10 @@ packages:
|
|
378
392
|
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
379
393
|
engines: {node: '>=12'}
|
380
394
|
|
395
|
+
'@istanbuljs/schema@0.1.3':
|
396
|
+
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
|
397
|
+
engines: {node: '>=8'}
|
398
|
+
|
381
399
|
'@jest/schemas@29.6.3':
|
382
400
|
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
|
383
401
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
@@ -872,6 +890,11 @@ packages:
|
|
872
890
|
'@ungap/structured-clone@1.2.0':
|
873
891
|
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
874
892
|
|
893
|
+
'@vitest/coverage-v8@1.6.0':
|
894
|
+
resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==}
|
895
|
+
peerDependencies:
|
896
|
+
vitest: 1.6.0
|
897
|
+
|
875
898
|
'@vitest/expect@1.6.0':
|
876
899
|
resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==}
|
877
900
|
|
@@ -1823,6 +1846,9 @@ packages:
|
|
1823
1846
|
resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==}
|
1824
1847
|
engines: {node: '>=8'}
|
1825
1848
|
|
1849
|
+
html-escaper@2.0.2:
|
1850
|
+
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
1851
|
+
|
1826
1852
|
http-cache-semantics@4.1.1:
|
1827
1853
|
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
|
1828
1854
|
|
@@ -1950,6 +1976,22 @@ packages:
|
|
1950
1976
|
isexe@2.0.0:
|
1951
1977
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
1952
1978
|
|
1979
|
+
istanbul-lib-coverage@3.2.2:
|
1980
|
+
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
|
1981
|
+
engines: {node: '>=8'}
|
1982
|
+
|
1983
|
+
istanbul-lib-report@3.0.1:
|
1984
|
+
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
|
1985
|
+
engines: {node: '>=10'}
|
1986
|
+
|
1987
|
+
istanbul-lib-source-maps@5.0.6:
|
1988
|
+
resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==}
|
1989
|
+
engines: {node: '>=10'}
|
1990
|
+
|
1991
|
+
istanbul-reports@3.1.7:
|
1992
|
+
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
|
1993
|
+
engines: {node: '>=8'}
|
1994
|
+
|
1953
1995
|
iterare@1.2.1:
|
1954
1996
|
resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
|
1955
1997
|
engines: {node: '>=6'}
|
@@ -2079,6 +2121,13 @@ packages:
|
|
2079
2121
|
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
2080
2122
|
engines: {node: '>=12'}
|
2081
2123
|
|
2124
|
+
magicast@0.3.4:
|
2125
|
+
resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==}
|
2126
|
+
|
2127
|
+
make-dir@4.0.0:
|
2128
|
+
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
2129
|
+
engines: {node: '>=10'}
|
2130
|
+
|
2082
2131
|
media-typer@0.3.0:
|
2083
2132
|
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
2084
2133
|
engines: {node: '>= 0.6'}
|
@@ -2863,6 +2912,10 @@ packages:
|
|
2863
2912
|
engines: {node: '>=10'}
|
2864
2913
|
hasBin: true
|
2865
2914
|
|
2915
|
+
test-exclude@6.0.0:
|
2916
|
+
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
|
2917
|
+
engines: {node: '>=8'}
|
2918
|
+
|
2866
2919
|
text-decoding@1.0.0:
|
2867
2920
|
resolution: {integrity: sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==}
|
2868
2921
|
|
@@ -2890,6 +2943,10 @@ packages:
|
|
2890
2943
|
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
|
2891
2944
|
engines: {node: '>=0.6.0'}
|
2892
2945
|
|
2946
|
+
to-fast-properties@2.0.0:
|
2947
|
+
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
2948
|
+
engines: {node: '>=4'}
|
2949
|
+
|
2893
2950
|
to-regex-range@5.0.1:
|
2894
2951
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
2895
2952
|
engines: {node: '>=8.0'}
|
@@ -3185,14 +3242,10 @@ packages:
|
|
3185
3242
|
|
3186
3243
|
snapshots:
|
3187
3244
|
|
3188
|
-
'@
|
3245
|
+
'@ampproject/remapping@2.3.0':
|
3189
3246
|
dependencies:
|
3190
|
-
'@
|
3191
|
-
'@
|
3192
|
-
'@nestjs/swagger': 7.4.0(@fastify/static@7.0.4)(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)
|
3193
|
-
openapi3-ts: 4.3.3
|
3194
|
-
ts-deepmerge: 6.2.1
|
3195
|
-
zod: 3.23.8
|
3247
|
+
'@jridgewell/gen-mapping': 0.3.5
|
3248
|
+
'@jridgewell/trace-mapping': 0.3.25
|
3196
3249
|
|
3197
3250
|
'@anatine/zod-openapi@2.2.6(openapi3-ts@4.3.3)(zod@3.23.8)':
|
3198
3251
|
dependencies:
|
@@ -3237,6 +3290,8 @@ snapshots:
|
|
3237
3290
|
'@babel/highlight': 7.24.7
|
3238
3291
|
picocolors: 1.0.1
|
3239
3292
|
|
3293
|
+
'@babel/helper-string-parser@7.24.8': {}
|
3294
|
+
|
3240
3295
|
'@babel/helper-validator-identifier@7.24.7': {}
|
3241
3296
|
|
3242
3297
|
'@babel/highlight@7.24.7':
|
@@ -3246,6 +3301,18 @@ snapshots:
|
|
3246
3301
|
js-tokens: 4.0.0
|
3247
3302
|
picocolors: 1.0.1
|
3248
3303
|
|
3304
|
+
'@babel/parser@7.25.4':
|
3305
|
+
dependencies:
|
3306
|
+
'@babel/types': 7.25.4
|
3307
|
+
|
3308
|
+
'@babel/types@7.25.4':
|
3309
|
+
dependencies:
|
3310
|
+
'@babel/helper-string-parser': 7.24.8
|
3311
|
+
'@babel/helper-validator-identifier': 7.24.7
|
3312
|
+
to-fast-properties: 2.0.0
|
3313
|
+
|
3314
|
+
'@bcoe/v8-coverage@0.2.3': {}
|
3315
|
+
|
3249
3316
|
'@colors/colors@1.5.0':
|
3250
3317
|
optional: true
|
3251
3318
|
|
@@ -3420,6 +3487,8 @@ snapshots:
|
|
3420
3487
|
wrap-ansi: 8.1.0
|
3421
3488
|
wrap-ansi-cjs: wrap-ansi@7.0.0
|
3422
3489
|
|
3490
|
+
'@istanbuljs/schema@0.1.3': {}
|
3491
|
+
|
3423
3492
|
'@jest/schemas@29.6.3':
|
3424
3493
|
dependencies:
|
3425
3494
|
'@sinclair/typebox': 0.27.8
|
@@ -3926,6 +3995,25 @@ snapshots:
|
|
3926
3995
|
|
3927
3996
|
'@ungap/structured-clone@1.2.0': {}
|
3928
3997
|
|
3998
|
+
'@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.12.12)(terser@5.31.3))':
|
3999
|
+
dependencies:
|
4000
|
+
'@ampproject/remapping': 2.3.0
|
4001
|
+
'@bcoe/v8-coverage': 0.2.3
|
4002
|
+
debug: 4.3.5
|
4003
|
+
istanbul-lib-coverage: 3.2.2
|
4004
|
+
istanbul-lib-report: 3.0.1
|
4005
|
+
istanbul-lib-source-maps: 5.0.6
|
4006
|
+
istanbul-reports: 3.1.7
|
4007
|
+
magic-string: 0.30.10
|
4008
|
+
magicast: 0.3.4
|
4009
|
+
picocolors: 1.0.1
|
4010
|
+
std-env: 3.7.0
|
4011
|
+
strip-literal: 2.1.0
|
4012
|
+
test-exclude: 6.0.0
|
4013
|
+
vitest: 1.6.0(@types/node@20.12.12)(terser@5.31.3)
|
4014
|
+
transitivePeerDependencies:
|
4015
|
+
- supports-color
|
4016
|
+
|
3929
4017
|
'@vitest/expect@1.6.0':
|
3930
4018
|
dependencies:
|
3931
4019
|
'@vitest/spy': 1.6.0
|
@@ -5057,6 +5145,8 @@ snapshots:
|
|
5057
5145
|
|
5058
5146
|
hexoid@1.0.0: {}
|
5059
5147
|
|
5148
|
+
html-escaper@2.0.2: {}
|
5149
|
+
|
5060
5150
|
http-cache-semantics@4.1.1: {}
|
5061
5151
|
|
5062
5152
|
http-errors@2.0.0:
|
@@ -5179,6 +5269,27 @@ snapshots:
|
|
5179
5269
|
|
5180
5270
|
isexe@2.0.0: {}
|
5181
5271
|
|
5272
|
+
istanbul-lib-coverage@3.2.2: {}
|
5273
|
+
|
5274
|
+
istanbul-lib-report@3.0.1:
|
5275
|
+
dependencies:
|
5276
|
+
istanbul-lib-coverage: 3.2.2
|
5277
|
+
make-dir: 4.0.0
|
5278
|
+
supports-color: 7.2.0
|
5279
|
+
|
5280
|
+
istanbul-lib-source-maps@5.0.6:
|
5281
|
+
dependencies:
|
5282
|
+
'@jridgewell/trace-mapping': 0.3.25
|
5283
|
+
debug: 4.3.5
|
5284
|
+
istanbul-lib-coverage: 3.2.2
|
5285
|
+
transitivePeerDependencies:
|
5286
|
+
- supports-color
|
5287
|
+
|
5288
|
+
istanbul-reports@3.1.7:
|
5289
|
+
dependencies:
|
5290
|
+
html-escaper: 2.0.2
|
5291
|
+
istanbul-lib-report: 3.0.1
|
5292
|
+
|
5182
5293
|
iterare@1.2.1: {}
|
5183
5294
|
|
5184
5295
|
jackspeak@3.4.3:
|
@@ -5321,6 +5432,16 @@ snapshots:
|
|
5321
5432
|
dependencies:
|
5322
5433
|
'@jridgewell/sourcemap-codec': 1.5.0
|
5323
5434
|
|
5435
|
+
magicast@0.3.4:
|
5436
|
+
dependencies:
|
5437
|
+
'@babel/parser': 7.25.4
|
5438
|
+
'@babel/types': 7.25.4
|
5439
|
+
source-map-js: 1.2.0
|
5440
|
+
|
5441
|
+
make-dir@4.0.0:
|
5442
|
+
dependencies:
|
5443
|
+
semver: 7.6.3
|
5444
|
+
|
5324
5445
|
media-typer@0.3.0: {}
|
5325
5446
|
|
5326
5447
|
memfs@3.5.3:
|
@@ -6070,6 +6191,12 @@ snapshots:
|
|
6070
6191
|
commander: 2.20.3
|
6071
6192
|
source-map-support: 0.5.21
|
6072
6193
|
|
6194
|
+
test-exclude@6.0.0:
|
6195
|
+
dependencies:
|
6196
|
+
'@istanbuljs/schema': 0.1.3
|
6197
|
+
glob: 7.2.3
|
6198
|
+
minimatch: 3.1.2
|
6199
|
+
|
6073
6200
|
text-decoding@1.0.0: {}
|
6074
6201
|
|
6075
6202
|
text-table@0.2.0: {}
|
@@ -6090,6 +6217,8 @@ snapshots:
|
|
6090
6217
|
dependencies:
|
6091
6218
|
os-tmpdir: 1.0.2
|
6092
6219
|
|
6220
|
+
to-fast-properties@2.0.0: {}
|
6221
|
+
|
6093
6222
|
to-regex-range@5.0.1:
|
6094
6223
|
dependencies:
|
6095
6224
|
is-number: 7.0.0
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { DomainError } from "./domain-error";
|
2
|
+
|
3
|
+
export class ValidationError extends DomainError {
|
4
|
+
public error = "ValidationError" as const;
|
5
|
+
public debug: object | null;
|
6
|
+
|
7
|
+
constructor(debug?: object) {
|
8
|
+
super("Os dados recebidos são inválidos.");
|
9
|
+
|
10
|
+
this.debug = debug ?? null;
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import {
|
2
|
+
ArgumentsHost,
|
3
|
+
Catch,
|
4
|
+
ExceptionFilter,
|
5
|
+
HttpException,
|
6
|
+
} from "@nestjs/common";
|
7
|
+
import { FastifyReply } from "fastify";
|
8
|
+
import { InternalServerError } from "../internal-server.error";
|
9
|
+
|
10
|
+
@Catch()
|
11
|
+
export class AllExceptionFilter implements ExceptionFilter {
|
12
|
+
catch(exception: unknown, host: ArgumentsHost): void {
|
13
|
+
const ctx = host.switchToHttp();
|
14
|
+
const response = ctx.getResponse<FastifyReply>();
|
15
|
+
|
16
|
+
const debug =
|
17
|
+
exception && typeof exception === "object" && "message" in exception
|
18
|
+
? exception.message
|
19
|
+
: null;
|
20
|
+
|
21
|
+
let httpException: HttpException = new InternalServerError(debug);
|
22
|
+
|
23
|
+
if (exception instanceof HttpException) httpException = exception;
|
24
|
+
|
25
|
+
console.error(exception);
|
26
|
+
|
27
|
+
response
|
28
|
+
.status(httpException.getStatus())
|
29
|
+
.send(httpException.getResponse());
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { DomainError } from "@/core/errors/domain-error";
|
2
|
+
import { ValidationError } from "@/core/errors/validation.error";
|
3
|
+
import { ErrorPresenter } from "@/infra/presenters/error.presenter";
|
4
|
+
import {
|
5
|
+
ArgumentsHost,
|
6
|
+
BadRequestException,
|
7
|
+
Catch,
|
8
|
+
ExceptionFilter,
|
9
|
+
HttpException,
|
10
|
+
} from "@nestjs/common";
|
11
|
+
import { FastifyReply } from "fastify";
|
12
|
+
import { InternalServerError } from "../internal-server.error";
|
13
|
+
|
14
|
+
@Catch(DomainError)
|
15
|
+
export class DomainExceptionFilter implements ExceptionFilter {
|
16
|
+
catch(exception: DomainError, host: ArgumentsHost): void {
|
17
|
+
const ctx = host.switchToHttp();
|
18
|
+
const response = ctx.getResponse<FastifyReply>();
|
19
|
+
|
20
|
+
let httpException: HttpException;
|
21
|
+
|
22
|
+
switch (exception.constructor) {
|
23
|
+
case ValidationError:
|
24
|
+
httpException = new BadRequestException(
|
25
|
+
ErrorPresenter.toHttp(400, exception),
|
26
|
+
);
|
27
|
+
break;
|
28
|
+
|
29
|
+
default:
|
30
|
+
httpException = new InternalServerError(exception.message);
|
31
|
+
}
|
32
|
+
|
33
|
+
console.error(exception);
|
34
|
+
|
35
|
+
response
|
36
|
+
.status(httpException.getStatus())
|
37
|
+
.send(httpException.getResponse());
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { ErrorPresenter } from "@/infra/presenters/error.presenter";
|
2
|
+
import { HttpException } from "@nestjs/common";
|
3
|
+
|
4
|
+
export class InternalServerError extends HttpException {
|
5
|
+
constructor(debug: unknown) {
|
6
|
+
const statusCode = 500;
|
7
|
+
const presenter = ErrorPresenter.toHttp(statusCode, {
|
8
|
+
error: "InternalServerError",
|
9
|
+
message: "Desculpe, um erro inesperado ocorreu.",
|
10
|
+
debug,
|
11
|
+
});
|
12
|
+
|
13
|
+
super(presenter, statusCode);
|
14
|
+
}
|
15
|
+
}
|
@@ -2,20 +2,20 @@ import { Module } from "@nestjs/common";
|
|
2
2
|
import { APP_FILTER } from "@nestjs/core";
|
3
3
|
import { HelloMultipartController } from "./controllers/hello/hello-multipart.controller";
|
4
4
|
import { HelloController } from "./controllers/hello/hello.controller";
|
5
|
+
import { AllExceptionFilter } from "./errors/filters/all-exception.filter";
|
6
|
+
import { DomainExceptionFilter } from "./errors/filters/domain-exception.filter";
|
5
7
|
import { FastifyMulterEventModule } from "./events/fastify-multer.event.module";
|
6
|
-
import { DomainExceptionFilter } from "./filters/domain-exception.filter";
|
7
|
-
import { HttpExceptionFilter } from "./filters/http-exception.filter";
|
8
8
|
|
9
9
|
@Module({
|
10
10
|
imports: [FastifyMulterEventModule],
|
11
11
|
providers: [
|
12
12
|
{
|
13
13
|
provide: APP_FILTER,
|
14
|
-
useClass:
|
14
|
+
useClass: AllExceptionFilter,
|
15
15
|
},
|
16
16
|
{
|
17
17
|
provide: APP_FILTER,
|
18
|
-
useClass:
|
18
|
+
useClass: DomainExceptionFilter,
|
19
19
|
},
|
20
20
|
],
|
21
21
|
controllers: [HelloController, HelloMultipartController],
|
@@ -15,9 +15,11 @@ import multer, {
|
|
15
15
|
memoryStorage,
|
16
16
|
} from "fastify-multer";
|
17
17
|
import { File, FileFilter, StorageEngine } from "fastify-multer/lib/interfaces";
|
18
|
+
import { unlink } from "fs/promises";
|
18
19
|
import { extension } from "mime-types";
|
19
20
|
import { extname } from "path";
|
20
21
|
import prettyBytes from "pretty-bytes";
|
22
|
+
import { finalize } from "rxjs";
|
21
23
|
import { ZodObject, ZodRawShape, z } from "zod";
|
22
24
|
import { UploadValidationError } from "../errors/upload-validation.error";
|
23
25
|
import { zodSchemaToSwaggerSchema } from "./zod-schema-pipe";
|
@@ -108,6 +110,12 @@ type UploadInterceptorOptions = Storage & {
|
|
108
110
|
* Infinity
|
109
111
|
*/
|
110
112
|
maxNonFileFieldSize?: number;
|
113
|
+
/**
|
114
|
+
* Removes all uploaded files after handler execution.
|
115
|
+
*
|
116
|
+
* @default true
|
117
|
+
*/
|
118
|
+
removeFilesAfterHandlerExecution?: boolean;
|
111
119
|
};
|
112
120
|
|
113
121
|
/**
|
@@ -123,6 +131,7 @@ export function UploadInterceptor(options: UploadInterceptorOptions) {
|
|
123
131
|
maxFileSize,
|
124
132
|
nonFileFieldsZodSchema,
|
125
133
|
maxNonFileFieldSize,
|
134
|
+
removeFilesAfterHandlerExecution,
|
126
135
|
...restOptions
|
127
136
|
} = {
|
128
137
|
destination: "./tmp",
|
@@ -132,6 +141,7 @@ export function UploadInterceptor(options: UploadInterceptorOptions) {
|
|
132
141
|
maxFileSize: 50,
|
133
142
|
nonFileFieldsZodSchema: z.object({}),
|
134
143
|
maxNonFileFieldSize: 1,
|
144
|
+
removeFilesAfterHandlerExecution: true,
|
135
145
|
...options,
|
136
146
|
};
|
137
147
|
const nonFileFieldsSwaggerSchema = zodSchemaToSwaggerSchema(
|
@@ -211,24 +221,28 @@ export function UploadInterceptor(options: UploadInterceptorOptions) {
|
|
211
221
|
};
|
212
222
|
|
213
223
|
const megabytesToBytes = (mb: number) => mb * 1000 * 1000;
|
224
|
+
const interceptors: NestInterceptor[] = [
|
225
|
+
new ExecuteUploadInterceptor({
|
226
|
+
multerInstance: multer({
|
227
|
+
storage: getMulterStorage(),
|
228
|
+
fileFilter: setMulterFileFilter,
|
229
|
+
limits: {
|
230
|
+
files: maxFileCount,
|
231
|
+
fileSize: megabytesToBytes(maxFileSize),
|
232
|
+
fields: Infinity,
|
233
|
+
fieldSize: megabytesToBytes(maxNonFileFieldSize),
|
234
|
+
},
|
235
|
+
}),
|
236
|
+
fieldName,
|
237
|
+
required,
|
238
|
+
}),
|
239
|
+
];
|
240
|
+
|
241
|
+
if (removeFilesAfterHandlerExecution)
|
242
|
+
interceptors.push(new RemoveUploadsInterceptor());
|
214
243
|
|
215
244
|
return applyDecorators(
|
216
|
-
UseInterceptors(
|
217
|
-
new ExecuteUploadInterceptor({
|
218
|
-
multerInstance: multer({
|
219
|
-
storage: getMulterStorage(),
|
220
|
-
fileFilter: setMulterFileFilter,
|
221
|
-
limits: {
|
222
|
-
files: maxFileCount,
|
223
|
-
fileSize: megabytesToBytes(maxFileSize),
|
224
|
-
fields: Object.keys(nonFileFieldsZodSchema.shape).length,
|
225
|
-
fieldSize: megabytesToBytes(maxNonFileFieldSize),
|
226
|
-
},
|
227
|
-
}),
|
228
|
-
fieldName,
|
229
|
-
required,
|
230
|
-
}),
|
231
|
-
),
|
245
|
+
UseInterceptors(...interceptors),
|
232
246
|
ApiConsumes("multipart/form-data"),
|
233
247
|
ApiBody({
|
234
248
|
schema: {
|
@@ -366,3 +380,26 @@ export class ExecuteUploadInterceptor implements NestInterceptor {
|
|
366
380
|
return next.handle();
|
367
381
|
}
|
368
382
|
}
|
383
|
+
|
384
|
+
export class RemoveUploadsInterceptor implements NestInterceptor {
|
385
|
+
intercept(context: ExecutionContext, next: CallHandler) {
|
386
|
+
const ctx = context.switchToHttp();
|
387
|
+
const request = ctx.getRequest<FastifyRequestWithFile>();
|
388
|
+
|
389
|
+
return next.handle().pipe(
|
390
|
+
finalize(async () => {
|
391
|
+
const { file, files } = request;
|
392
|
+
|
393
|
+
if (file && file.path) await unlink(file.path);
|
394
|
+
|
395
|
+
if (files) {
|
396
|
+
await Promise.all(
|
397
|
+
files.map(async file => {
|
398
|
+
if (file.path) return unlink(file.path);
|
399
|
+
}),
|
400
|
+
);
|
401
|
+
}
|
402
|
+
}),
|
403
|
+
);
|
404
|
+
}
|
405
|
+
}
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
import { extendApi, generateSchema } from "@anatine/zod-openapi";
|
1
|
+
import { generateSchema } from "@anatine/zod-openapi";
|
3
2
|
import { UsePipes, applyDecorators } from "@nestjs/common";
|
4
3
|
import { ZodType } from "zod";
|
5
4
|
import {
|
@@ -15,10 +14,6 @@ export function zodSchemaToSwaggerSchema(schema: ZodType) {
|
|
15
14
|
return generateSchema(schema, false, "3.0") as SchemaObject;
|
16
15
|
}
|
17
16
|
|
18
|
-
export function zodSchemaToNestDto(schema: ZodType) {
|
19
|
-
return class Dto extends createZodDto(extendApi(schema)) {};
|
20
|
-
}
|
21
|
-
|
22
17
|
interface ZodSchemaPipeParams extends ZodValidationPipeSchemas {
|
23
18
|
isMultipart?: boolean;
|
24
19
|
response?: ZodType | Record<number, ZodType>;
|
@@ -38,17 +33,35 @@ export function ZodSchemaPipe({
|
|
38
33
|
const apiDecorators: NestSwaggerDecorator[] = [];
|
39
34
|
|
40
35
|
if (routeParams) {
|
41
|
-
|
42
|
-
|
43
|
-
)
|
36
|
+
const routeParamsSchema = zodSchemaToSwaggerSchema(routeParams);
|
37
|
+
|
38
|
+
for (const paramName in routeParams.shape) {
|
39
|
+
apiDecorators.push(
|
40
|
+
ApiParam({
|
41
|
+
name: paramName,
|
42
|
+
schema: zodSchemaToSwaggerSchema(routeParams.shape[paramName]),
|
43
|
+
required: routeParamsSchema.required?.includes(paramName) ?? false,
|
44
|
+
}),
|
45
|
+
);
|
46
|
+
}
|
44
47
|
}
|
45
48
|
|
46
49
|
if (queryParams) {
|
47
|
-
|
50
|
+
const queryParamsSchema = zodSchemaToSwaggerSchema(queryParams);
|
51
|
+
|
52
|
+
for (const paramName in queryParams.shape) {
|
53
|
+
apiDecorators.push(
|
54
|
+
ApiQuery({
|
55
|
+
name: paramName,
|
56
|
+
schema: zodSchemaToSwaggerSchema(queryParams.shape[paramName]),
|
57
|
+
required: queryParamsSchema.required?.includes(paramName) ?? false,
|
58
|
+
}),
|
59
|
+
);
|
60
|
+
}
|
48
61
|
}
|
49
62
|
|
50
63
|
if (body && !isMultipart) {
|
51
|
-
apiDecorators.push(ApiBody({
|
64
|
+
apiDecorators.push(ApiBody({ schema: zodSchemaToSwaggerSchema(body) }));
|
52
65
|
}
|
53
66
|
|
54
67
|
if (response) {
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { ValidationError } from "@/core/errors/
|
1
|
+
import { ValidationError } from "@/core/errors/validation.error";
|
2
2
|
import { ArgumentMetadata, PipeTransform } from "@nestjs/common";
|
3
|
-
import { ZodError, ZodType } from "zod";
|
3
|
+
import { ZodError, ZodObject, ZodRawShape, ZodType } from "zod";
|
4
4
|
|
5
5
|
export interface ZodValidationPipeSchemas {
|
6
|
-
routeParams?:
|
7
|
-
queryParams?:
|
6
|
+
routeParams?: ZodObject<ZodRawShape>;
|
7
|
+
queryParams?: ZodObject<ZodRawShape>;
|
8
8
|
body?: ZodType;
|
9
9
|
}
|
10
10
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { DomainError } from "@/core/errors/domain-error";
|
2
|
+
import { env } from "../env";
|
2
3
|
|
3
4
|
type CustomError = Pick<DomainError, "error" | "message" | "debug">;
|
4
5
|
|
@@ -8,7 +9,7 @@ export class ErrorPresenter {
|
|
8
9
|
error: error.error,
|
9
10
|
message: error.message,
|
10
11
|
statusCode,
|
11
|
-
debug: error.debug,
|
12
|
+
debug: env.NODE_ENV !== "production" ? error.debug : null,
|
12
13
|
};
|
13
14
|
}
|
14
15
|
}
|
@@ -1,53 +0,0 @@
|
|
1
|
-
import { DomainError } from "@/core/errors/domain-error";
|
2
|
-
import { ValidationError } from "@/core/errors/errors";
|
3
|
-
import { env } from "@/infra/env";
|
4
|
-
import { ErrorPresenter } from "@/infra/presenters/error.presenter";
|
5
|
-
import {
|
6
|
-
ArgumentsHost,
|
7
|
-
BadRequestException,
|
8
|
-
Catch,
|
9
|
-
ExceptionFilter,
|
10
|
-
HttpException,
|
11
|
-
HttpStatus,
|
12
|
-
InternalServerErrorException,
|
13
|
-
} from "@nestjs/common";
|
14
|
-
import { FastifyReply } from "fastify";
|
15
|
-
|
16
|
-
@Catch(DomainError)
|
17
|
-
export class DomainExceptionFilter implements ExceptionFilter {
|
18
|
-
catch(exception: DomainError, host: ArgumentsHost): void {
|
19
|
-
const ctx = host.switchToHttp();
|
20
|
-
const response = ctx.getResponse<FastifyReply>();
|
21
|
-
|
22
|
-
let httpException: HttpException;
|
23
|
-
|
24
|
-
switch (exception.constructor) {
|
25
|
-
case ValidationError:
|
26
|
-
httpException = new BadRequestException(
|
27
|
-
ErrorPresenter.toHttp(HttpStatus.BAD_REQUEST, exception),
|
28
|
-
);
|
29
|
-
break;
|
30
|
-
|
31
|
-
default:
|
32
|
-
httpException = new InternalServerErrorException(
|
33
|
-
ErrorPresenter.toHttp(HttpStatus.INTERNAL_SERVER_ERROR, {
|
34
|
-
error: "InternalServerError",
|
35
|
-
message: "Desculpe, um erro inesperado ocorreu.",
|
36
|
-
debug: exception.message,
|
37
|
-
}),
|
38
|
-
);
|
39
|
-
break;
|
40
|
-
}
|
41
|
-
|
42
|
-
const httpResponse = httpException.getResponse();
|
43
|
-
|
44
|
-
if (
|
45
|
-
env.NODE_ENV === "production" &&
|
46
|
-
typeof httpResponse === "object" &&
|
47
|
-
"debug" in httpResponse
|
48
|
-
)
|
49
|
-
delete httpResponse.debug;
|
50
|
-
|
51
|
-
response.status(httpException.getStatus()).send(httpResponse);
|
52
|
-
}
|
53
|
-
}
|
@@ -1,26 +0,0 @@
|
|
1
|
-
import { env } from "@/infra/env";
|
2
|
-
import {
|
3
|
-
ArgumentsHost,
|
4
|
-
Catch,
|
5
|
-
ExceptionFilter,
|
6
|
-
HttpException,
|
7
|
-
} from "@nestjs/common";
|
8
|
-
import { FastifyReply } from "fastify";
|
9
|
-
|
10
|
-
@Catch(HttpException)
|
11
|
-
export class HttpExceptionFilter implements ExceptionFilter {
|
12
|
-
catch(httpException: HttpException, host: ArgumentsHost): void {
|
13
|
-
const ctx = host.switchToHttp();
|
14
|
-
const response = ctx.getResponse<FastifyReply>();
|
15
|
-
const httpResponse = httpException.getResponse();
|
16
|
-
|
17
|
-
if (
|
18
|
-
env.NODE_ENV === "production" &&
|
19
|
-
typeof httpResponse === "object" &&
|
20
|
-
"debug" in httpResponse
|
21
|
-
)
|
22
|
-
delete httpResponse.debug;
|
23
|
-
|
24
|
-
response.status(httpException.getStatus()).send(httpResponse);
|
25
|
-
}
|
26
|
-
}
|