@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.
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.",
|
@@ -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
|
+
}
|