@leo-h/create-nodejs-app 1.0.13 → 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.
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0});const name="@leo-h/create-nodejs-app",version="1.0.13",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;
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.13",
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.",
@@ -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": {
@@ -41,6 +41,9 @@ importers:
41
41
  pretty-bytes:
42
42
  specifier: 5.6.0
43
43
  version: 5.6.0
44
+ rxjs:
45
+ specifier: 7.8.1
46
+ version: 7.8.1
44
47
  zod:
45
48
  specifier: 3.23.8
46
49
  version: 3.23.8
@@ -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
+ }