sprint-es 0.0.156 → 0.0.157
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/cjs/index.cjs +77 -8
- package/dist/cjs/modules/schemas/index.cjs +134 -3
- package/dist/esm/index.js +77 -8
- package/dist/esm/modules/schemas/index.js +134 -3
- package/dist/types/modules/schemas/index.d.ts +34 -1
- package/dist/types/modules/schemas/index.d.ts.map +1 -1
- package/dist/types/modules/schemas/types.d.ts +16 -0
- package/dist/types/modules/schemas/types.d.ts.map +1 -1
- package/dist/types/sprint.d.ts +23 -3
- package/dist/types/sprint.d.ts.map +1 -1
- package/dist/types/types.d.ts +4 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/package.json +3 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -29,6 +29,8 @@ const cors = require("cors");
|
|
|
29
29
|
const path = require("path");
|
|
30
30
|
const morgan = require("morgan");
|
|
31
31
|
const dotenv = require("dotenv");
|
|
32
|
+
const multer = require("multer");
|
|
33
|
+
const busboy = require("busboy");
|
|
32
34
|
const url = require("url");
|
|
33
35
|
const rateLimit = require("toolkitify/rate-limit");
|
|
34
36
|
const modules_schemas_index = require("./modules/schemas/index.cjs");
|
|
@@ -85,10 +87,7 @@ const isProduction = isProd;
|
|
|
85
87
|
function isEnabledInEnv(value) {
|
|
86
88
|
if (value === void 0) return false;
|
|
87
89
|
if (typeof value === "boolean") return value;
|
|
88
|
-
if (Array.isArray(value))
|
|
89
|
-
const env = nodeEnv || "development";
|
|
90
|
-
return value.includes(env);
|
|
91
|
-
}
|
|
90
|
+
if (Array.isArray(value)) return value.includes(nodeEnv || "development");
|
|
92
91
|
return false;
|
|
93
92
|
}
|
|
94
93
|
async function findProjectRoot(startDir) {
|
|
@@ -146,6 +145,7 @@ class Sprint {
|
|
|
146
145
|
};
|
|
147
146
|
this.graphqlSchema = null;
|
|
148
147
|
this.registeredRoutes = [];
|
|
148
|
+
this.fileMemoryUploadedLimit = 5 * 1024 * 1024;
|
|
149
149
|
this.app = express();
|
|
150
150
|
loadSprintConfig().then((config) => {
|
|
151
151
|
const defaults = {
|
|
@@ -194,6 +194,7 @@ class Sprint {
|
|
|
194
194
|
path: finalConfig.graphql?.graphiql?.path || "/graphiql"
|
|
195
195
|
}
|
|
196
196
|
};
|
|
197
|
+
this.fileMemoryUploadedLimit = finalConfig.fileMemoryUploadedLimit || 5 * 1024 * 1024;
|
|
197
198
|
const openApiPath = this.openapi.path;
|
|
198
199
|
const swaggerPath = this.openapi.swaggerUi.path;
|
|
199
200
|
const graphqlPath = this.graphql.path;
|
|
@@ -219,6 +220,10 @@ class Sprint {
|
|
|
219
220
|
this.loadDefaults();
|
|
220
221
|
this.loadHealthcheck();
|
|
221
222
|
this.routesLoaded = this.init();
|
|
223
|
+
this.memoryUpload = multer({
|
|
224
|
+
storage: multer.memoryStorage(),
|
|
225
|
+
limits: { fileSize: this.fileMemoryUploadedLimit }
|
|
226
|
+
});
|
|
222
227
|
this.routesLoaded.then(async () => {
|
|
223
228
|
if (this.openapi.generateOnBuild) {
|
|
224
229
|
this.app.get(this.openapi.path, (_, res) => {
|
|
@@ -350,7 +355,7 @@ class Sprint {
|
|
|
350
355
|
this.app.use(express.urlencoded({ limit: this.urlEncodedLimit, extended: false }));
|
|
351
356
|
}
|
|
352
357
|
/**
|
|
353
|
-
* Gets all matching middlewares for a given route path, sorted by priority
|
|
358
|
+
* Gets all matching middlewares for a given route path, sorted by priority.
|
|
354
359
|
*/
|
|
355
360
|
getMiddlewaresForRoute(routePath) {
|
|
356
361
|
const matched = [];
|
|
@@ -374,7 +379,7 @@ class Sprint {
|
|
|
374
379
|
return matched.map((m) => m.handler);
|
|
375
380
|
}
|
|
376
381
|
/**
|
|
377
|
-
* Load all middleware files from the middlewares folder
|
|
382
|
+
* Load all middleware files from the middlewares folder.
|
|
378
383
|
*/
|
|
379
384
|
async loadMiddlewares(middlewaresPath) {
|
|
380
385
|
const fileExtensions = isProd ? [".mjs", ".js"] : [".ts"];
|
|
@@ -459,11 +464,37 @@ class Sprint {
|
|
|
459
464
|
}
|
|
460
465
|
}
|
|
461
466
|
const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
|
|
467
|
+
let fileUploadMiddleware = null;
|
|
468
|
+
for (const layer of router.stack) {
|
|
469
|
+
if (!layer.route) continue;
|
|
470
|
+
for (const routeLayer of layer.route.stack) {
|
|
471
|
+
const handler = routeLayer.handle;
|
|
472
|
+
const handlerSchema = handler.__sprintRouteSchema;
|
|
473
|
+
if (handlerSchema?.files && typeof handlerSchema.files === "object" && "field" in handlerSchema.files) {
|
|
474
|
+
const fileConfig = handlerSchema.files;
|
|
475
|
+
if (fileConfig.maxCount) {
|
|
476
|
+
fileUploadMiddleware = this.uploadFiles(fileConfig.field);
|
|
477
|
+
} else {
|
|
478
|
+
fileUploadMiddleware = this.uploadFile(fileConfig.field);
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (fileUploadMiddleware) break;
|
|
484
|
+
}
|
|
462
485
|
if (routeMiddlewares.length > 0) {
|
|
463
|
-
|
|
486
|
+
if (fileUploadMiddleware) {
|
|
487
|
+
this.app.use(finalRoute, fileUploadMiddleware, ...routeMiddlewares, router);
|
|
488
|
+
} else {
|
|
489
|
+
this.app.use(finalRoute, ...routeMiddlewares, router);
|
|
490
|
+
}
|
|
464
491
|
if (isVerbose) console.log(`[Sprint] Loaded route: ${finalRoute} -> ${filePath} (with ${routeMiddlewares.length} middleware(s))`);
|
|
465
492
|
} else {
|
|
466
|
-
|
|
493
|
+
if (fileUploadMiddleware) {
|
|
494
|
+
this.app.use(finalRoute, fileUploadMiddleware, router);
|
|
495
|
+
} else {
|
|
496
|
+
this.app.use(finalRoute, router);
|
|
497
|
+
}
|
|
467
498
|
if (isVerbose) console.log(`[Sprint] Loaded route: ${finalRoute} -> ${filePath}`);
|
|
468
499
|
}
|
|
469
500
|
this.counters.routes += router.stack.length;
|
|
@@ -828,6 +859,44 @@ class Sprint {
|
|
|
828
859
|
tryListen(basePort);
|
|
829
860
|
if (callback) callback();
|
|
830
861
|
}
|
|
862
|
+
uploadFile(fieldName = "file") {
|
|
863
|
+
return this.memoryUpload.single(fieldName);
|
|
864
|
+
}
|
|
865
|
+
uploadFiles(fieldNames = "files") {
|
|
866
|
+
if (Array.isArray(fieldNames)) return this.memoryUpload.fields(fieldNames.map((name) => ({ name })));
|
|
867
|
+
return this.memoryUpload.array(fieldNames);
|
|
868
|
+
}
|
|
869
|
+
streamUpload(options) {
|
|
870
|
+
return (req, res) => {
|
|
871
|
+
return new Promise((resolve, reject) => {
|
|
872
|
+
const bb = busboy({
|
|
873
|
+
headers: req.headers,
|
|
874
|
+
limits: options?.limits
|
|
875
|
+
});
|
|
876
|
+
const files = [];
|
|
877
|
+
const fields = {};
|
|
878
|
+
bb.on("file", (fieldName, file, info) => {
|
|
879
|
+
files.push({
|
|
880
|
+
fieldName,
|
|
881
|
+
file,
|
|
882
|
+
filename: info.filename,
|
|
883
|
+
encoding: info.encoding,
|
|
884
|
+
mimeType: info.mimeType
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
bb.on("field", (fieldName, val) => {
|
|
888
|
+
fields[fieldName] = val;
|
|
889
|
+
});
|
|
890
|
+
bb.on("finish", () => {
|
|
891
|
+
resolve({ files, fields });
|
|
892
|
+
});
|
|
893
|
+
bb.on("error", (err) => {
|
|
894
|
+
reject(err);
|
|
895
|
+
});
|
|
896
|
+
req.pipe(bb);
|
|
897
|
+
});
|
|
898
|
+
};
|
|
899
|
+
}
|
|
831
900
|
}
|
|
832
901
|
function createSchemaValidationMiddleware(schema) {
|
|
833
902
|
const headersSchema = schema.headers ? modules_schemas_index.normalizeHeadersSchema(schema.headers) : null;
|
|
@@ -1,6 +1,110 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const zod = require("zod");
|
|
4
|
+
function normalizeExtensions(ext) {
|
|
5
|
+
if (!ext) return [];
|
|
6
|
+
return (Array.isArray(ext) ? ext : [ext]).map((e) => e.toLowerCase().startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
|
|
7
|
+
}
|
|
8
|
+
function normalizeMimeTypes(mime) {
|
|
9
|
+
if (!mime) return [];
|
|
10
|
+
return (Array.isArray(mime) ? mime : [mime]).map((m) => m.toLowerCase());
|
|
11
|
+
}
|
|
12
|
+
function createFileSchema(options = {}) {
|
|
13
|
+
const extensions = normalizeExtensions(options.ext);
|
|
14
|
+
const mimeTypes = normalizeMimeTypes(options.mimeType);
|
|
15
|
+
const fileSchema = zod.z.object({
|
|
16
|
+
fieldname: zod.z.string(),
|
|
17
|
+
originalname: zod.z.string(),
|
|
18
|
+
encoding: zod.z.string(),
|
|
19
|
+
mimetype: zod.z.string(),
|
|
20
|
+
size: zod.z.number(),
|
|
21
|
+
buffer: zod.z.instanceof(Buffer).optional()
|
|
22
|
+
});
|
|
23
|
+
return fileSchema.refine((file) => {
|
|
24
|
+
if (extensions.length === 0) return true;
|
|
25
|
+
const fileExt = file.originalname.toLowerCase().substring(file.originalname.lastIndexOf("."));
|
|
26
|
+
return extensions.includes(fileExt);
|
|
27
|
+
}, {
|
|
28
|
+
message: `Invalid file extension. Allowed: ${extensions.join(", ")}`,
|
|
29
|
+
path: ["originalname"]
|
|
30
|
+
}).refine((file) => {
|
|
31
|
+
if (mimeTypes.length === 0) return true;
|
|
32
|
+
return mimeTypes.includes(file.mimetype.toLowerCase());
|
|
33
|
+
}, {
|
|
34
|
+
message: `Invalid mime type. Allowed: ${mimeTypes.join(", ")}`,
|
|
35
|
+
path: ["mimetype"]
|
|
36
|
+
}).refine((file) => {
|
|
37
|
+
if (options.maxSize === void 0) return true;
|
|
38
|
+
return file.size <= options.maxSize;
|
|
39
|
+
}, {
|
|
40
|
+
message: `File size exceeds maximum of ${options.maxSize} bytes`,
|
|
41
|
+
path: ["size"]
|
|
42
|
+
}).refine((file) => {
|
|
43
|
+
if (options.minSize === void 0) return true;
|
|
44
|
+
return file.size >= options.minSize;
|
|
45
|
+
}, {
|
|
46
|
+
message: `File size must be at least ${options.minSize} bytes`,
|
|
47
|
+
path: ["size"]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function createFilesArraySchema(fieldName, options = {}) {
|
|
51
|
+
const fileSchema = createFileSchema({ ...options });
|
|
52
|
+
return zod.z.array(fileSchema).min(options.required === false ? 0 : 1, {
|
|
53
|
+
message: options.required === false ? void 0 : `At least one file is required for field "${fieldName}"`
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const fileValidators = {
|
|
57
|
+
ext: (ext) => {
|
|
58
|
+
const extensions = normalizeExtensions(ext);
|
|
59
|
+
return createFileSchema({ ext: extensions });
|
|
60
|
+
},
|
|
61
|
+
mimeType: (mimeType) => {
|
|
62
|
+
const mimeTypes = normalizeMimeTypes(mimeType);
|
|
63
|
+
return createFileSchema({ mimeType: mimeTypes });
|
|
64
|
+
},
|
|
65
|
+
maxSize: (maxSize) => {
|
|
66
|
+
return createFileSchema({ maxSize });
|
|
67
|
+
},
|
|
68
|
+
minSize: (minSize) => {
|
|
69
|
+
return createFileSchema({ minSize });
|
|
70
|
+
},
|
|
71
|
+
image: () => {
|
|
72
|
+
return createFileSchema({
|
|
73
|
+
mimeType: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
|
|
74
|
+
ext: ["jpg", "jpeg", "png", "gif", "webp", "svg"]
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
document: () => {
|
|
78
|
+
return createFileSchema({
|
|
79
|
+
mimeType: ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "text/plain"],
|
|
80
|
+
ext: ["pdf", "doc", "docx", "txt"]
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
video: () => {
|
|
84
|
+
return createFileSchema({
|
|
85
|
+
mimeType: ["video/mp4", "video/webm", "video/ogg"],
|
|
86
|
+
ext: ["mp4", "webm", "ogg"]
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
audio: () => {
|
|
90
|
+
return createFileSchema({
|
|
91
|
+
mimeType: ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"],
|
|
92
|
+
ext: ["mp3", "wav", "ogg", "webm"]
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
archive: () => {
|
|
96
|
+
return createFileSchema({
|
|
97
|
+
mimeType: ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"],
|
|
98
|
+
ext: ["zip", "rar", "7z"]
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
any: () => {
|
|
102
|
+
return createFileSchema({});
|
|
103
|
+
},
|
|
104
|
+
field: (fieldName, options) => {
|
|
105
|
+
return createFilesArraySchema(fieldName, options);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
4
108
|
function normalizeHeadersSchema(schema) {
|
|
5
109
|
const shape = schema.shape ?? schema._def?.shape?.();
|
|
6
110
|
if (!shape) return schema;
|
|
@@ -25,6 +129,7 @@ Object.assign(sprintCallable, sprintAuth);
|
|
|
25
129
|
const proxyZ = new Proxy(zod.z, {
|
|
26
130
|
get(target, prop) {
|
|
27
131
|
if (prop === "sprint") return sprintCallable;
|
|
132
|
+
if (prop === "files") return fileValidators;
|
|
28
133
|
return target[prop];
|
|
29
134
|
}
|
|
30
135
|
});
|
|
@@ -43,6 +148,7 @@ function parseSchema(schema, data) {
|
|
|
43
148
|
}
|
|
44
149
|
function defineRouteSchema(schema) {
|
|
45
150
|
const headersSchema = schema.headers ? normalizeHeadersSchema(schema.headers) : null;
|
|
151
|
+
const fileConfig = typeof schema.files === "object" && "field" in schema.files ? schema.files : null;
|
|
46
152
|
const middleware = (req, res, next) => {
|
|
47
153
|
const errors = [];
|
|
48
154
|
const method = req.method.toUpperCase();
|
|
@@ -64,6 +170,24 @@ function defineRouteSchema(schema) {
|
|
|
64
170
|
const result = headersSchema.safeParse(normalizedHeaders);
|
|
65
171
|
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "headers", ...e })));
|
|
66
172
|
}
|
|
173
|
+
let filesData = [];
|
|
174
|
+
if (schema.files) {
|
|
175
|
+
if (fileConfig) {
|
|
176
|
+
const fieldFiles = req.file ? [req.file] : [];
|
|
177
|
+
const multiFiles = req.files?.[fileConfig.field] || [];
|
|
178
|
+
filesData = [...fieldFiles, ...Array.isArray(multiFiles) ? multiFiles : []];
|
|
179
|
+
if (fileConfig.maxCount && filesData.length > fileConfig.maxCount) errors.push({ location: "files", path: fileConfig.field, message: `Maximum ${fileConfig.maxCount} files allowed` });
|
|
180
|
+
if (fileConfig.schema && filesData.length > 0) {
|
|
181
|
+
const result = parseSchema(fileConfig.schema, filesData);
|
|
182
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
const filesSchema = schema.files;
|
|
186
|
+
const reqFiles = req.files || (req.file ? [req.file] : []);
|
|
187
|
+
const result = parseSchema(filesSchema, reqFiles);
|
|
188
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
67
191
|
if (schema.sprint?.authorization) {
|
|
68
192
|
const authSchema = schema.sprint.authorization;
|
|
69
193
|
const description = authSchema._def?.description;
|
|
@@ -71,9 +195,7 @@ function defineRouteSchema(schema) {
|
|
|
71
195
|
if (description) {
|
|
72
196
|
try {
|
|
73
197
|
const parsed = JSON.parse(description);
|
|
74
|
-
if (parsed.__sprintAuthorization && parsed.sources)
|
|
75
|
-
sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
|
|
76
|
-
}
|
|
198
|
+
if (parsed.__sprintAuthorization && parsed.sources) sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
|
|
77
199
|
} catch {
|
|
78
200
|
}
|
|
79
201
|
}
|
|
@@ -105,9 +227,18 @@ function defineRouteSchema(schema) {
|
|
|
105
227
|
next();
|
|
106
228
|
};
|
|
107
229
|
middleware.__sprintRouteSchema = schema;
|
|
230
|
+
if (fileConfig) {
|
|
231
|
+
middleware.applyFileUpload = function(sprint) {
|
|
232
|
+
if (fileConfig.maxCount) return sprint.uploadFiles(fileConfig.field);
|
|
233
|
+
return sprint.uploadFile(fileConfig.field);
|
|
234
|
+
};
|
|
235
|
+
}
|
|
108
236
|
return middleware;
|
|
109
237
|
}
|
|
238
|
+
exports.createFileSchema = createFileSchema;
|
|
239
|
+
exports.createFilesArraySchema = createFilesArraySchema;
|
|
110
240
|
exports.defineRouteSchema = defineRouteSchema;
|
|
241
|
+
exports.files = fileValidators;
|
|
111
242
|
exports.normalizeHeadersSchema = normalizeHeadersSchema;
|
|
112
243
|
exports.sprint = sprintBuilder;
|
|
113
244
|
exports.z = proxyZ;
|
package/dist/esm/index.js
CHANGED
|
@@ -5,6 +5,8 @@ import cors from "cors";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import morgan from "morgan";
|
|
7
7
|
import dotenv from "dotenv";
|
|
8
|
+
import multer from "multer";
|
|
9
|
+
import busboy from "busboy";
|
|
8
10
|
import { pathToFileURL } from "url";
|
|
9
11
|
import { RateLimiter } from "toolkitify/rate-limit";
|
|
10
12
|
import { normalizeHeadersSchema } from "./modules/schemas/index.js";
|
|
@@ -60,10 +62,7 @@ const isProduction = isProd;
|
|
|
60
62
|
function isEnabledInEnv(value) {
|
|
61
63
|
if (value === void 0) return false;
|
|
62
64
|
if (typeof value === "boolean") return value;
|
|
63
|
-
if (Array.isArray(value))
|
|
64
|
-
const env = nodeEnv || "development";
|
|
65
|
-
return value.includes(env);
|
|
66
|
-
}
|
|
65
|
+
if (Array.isArray(value)) return value.includes(nodeEnv || "development");
|
|
67
66
|
return false;
|
|
68
67
|
}
|
|
69
68
|
async function findProjectRoot(startDir) {
|
|
@@ -121,6 +120,7 @@ class Sprint {
|
|
|
121
120
|
};
|
|
122
121
|
this.graphqlSchema = null;
|
|
123
122
|
this.registeredRoutes = [];
|
|
123
|
+
this.fileMemoryUploadedLimit = 5 * 1024 * 1024;
|
|
124
124
|
this.app = express();
|
|
125
125
|
loadSprintConfig().then((config) => {
|
|
126
126
|
const defaults = {
|
|
@@ -169,6 +169,7 @@ class Sprint {
|
|
|
169
169
|
path: finalConfig.graphql?.graphiql?.path || "/graphiql"
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
|
+
this.fileMemoryUploadedLimit = finalConfig.fileMemoryUploadedLimit || 5 * 1024 * 1024;
|
|
172
173
|
const openApiPath = this.openapi.path;
|
|
173
174
|
const swaggerPath = this.openapi.swaggerUi.path;
|
|
174
175
|
const graphqlPath = this.graphql.path;
|
|
@@ -194,6 +195,10 @@ class Sprint {
|
|
|
194
195
|
this.loadDefaults();
|
|
195
196
|
this.loadHealthcheck();
|
|
196
197
|
this.routesLoaded = this.init();
|
|
198
|
+
this.memoryUpload = multer({
|
|
199
|
+
storage: multer.memoryStorage(),
|
|
200
|
+
limits: { fileSize: this.fileMemoryUploadedLimit }
|
|
201
|
+
});
|
|
197
202
|
this.routesLoaded.then(async () => {
|
|
198
203
|
if (this.openapi.generateOnBuild) {
|
|
199
204
|
this.app.get(this.openapi.path, (_, res) => {
|
|
@@ -325,7 +330,7 @@ class Sprint {
|
|
|
325
330
|
this.app.use(express.urlencoded({ limit: this.urlEncodedLimit, extended: false }));
|
|
326
331
|
}
|
|
327
332
|
/**
|
|
328
|
-
* Gets all matching middlewares for a given route path, sorted by priority
|
|
333
|
+
* Gets all matching middlewares for a given route path, sorted by priority.
|
|
329
334
|
*/
|
|
330
335
|
getMiddlewaresForRoute(routePath) {
|
|
331
336
|
const matched = [];
|
|
@@ -349,7 +354,7 @@ class Sprint {
|
|
|
349
354
|
return matched.map((m) => m.handler);
|
|
350
355
|
}
|
|
351
356
|
/**
|
|
352
|
-
* Load all middleware files from the middlewares folder
|
|
357
|
+
* Load all middleware files from the middlewares folder.
|
|
353
358
|
*/
|
|
354
359
|
async loadMiddlewares(middlewaresPath) {
|
|
355
360
|
const fileExtensions = isProd ? [".mjs", ".js"] : [".ts"];
|
|
@@ -434,11 +439,37 @@ class Sprint {
|
|
|
434
439
|
}
|
|
435
440
|
}
|
|
436
441
|
const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
|
|
442
|
+
let fileUploadMiddleware = null;
|
|
443
|
+
for (const layer of router.stack) {
|
|
444
|
+
if (!layer.route) continue;
|
|
445
|
+
for (const routeLayer of layer.route.stack) {
|
|
446
|
+
const handler = routeLayer.handle;
|
|
447
|
+
const handlerSchema = handler.__sprintRouteSchema;
|
|
448
|
+
if (handlerSchema?.files && typeof handlerSchema.files === "object" && "field" in handlerSchema.files) {
|
|
449
|
+
const fileConfig = handlerSchema.files;
|
|
450
|
+
if (fileConfig.maxCount) {
|
|
451
|
+
fileUploadMiddleware = this.uploadFiles(fileConfig.field);
|
|
452
|
+
} else {
|
|
453
|
+
fileUploadMiddleware = this.uploadFile(fileConfig.field);
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (fileUploadMiddleware) break;
|
|
459
|
+
}
|
|
437
460
|
if (routeMiddlewares.length > 0) {
|
|
438
|
-
|
|
461
|
+
if (fileUploadMiddleware) {
|
|
462
|
+
this.app.use(finalRoute, fileUploadMiddleware, ...routeMiddlewares, router);
|
|
463
|
+
} else {
|
|
464
|
+
this.app.use(finalRoute, ...routeMiddlewares, router);
|
|
465
|
+
}
|
|
439
466
|
if (isVerbose) console.log(`[Sprint] Loaded route: ${finalRoute} -> ${filePath} (with ${routeMiddlewares.length} middleware(s))`);
|
|
440
467
|
} else {
|
|
441
|
-
|
|
468
|
+
if (fileUploadMiddleware) {
|
|
469
|
+
this.app.use(finalRoute, fileUploadMiddleware, router);
|
|
470
|
+
} else {
|
|
471
|
+
this.app.use(finalRoute, router);
|
|
472
|
+
}
|
|
442
473
|
if (isVerbose) console.log(`[Sprint] Loaded route: ${finalRoute} -> ${filePath}`);
|
|
443
474
|
}
|
|
444
475
|
this.counters.routes += router.stack.length;
|
|
@@ -803,6 +834,44 @@ class Sprint {
|
|
|
803
834
|
tryListen(basePort);
|
|
804
835
|
if (callback) callback();
|
|
805
836
|
}
|
|
837
|
+
uploadFile(fieldName = "file") {
|
|
838
|
+
return this.memoryUpload.single(fieldName);
|
|
839
|
+
}
|
|
840
|
+
uploadFiles(fieldNames = "files") {
|
|
841
|
+
if (Array.isArray(fieldNames)) return this.memoryUpload.fields(fieldNames.map((name) => ({ name })));
|
|
842
|
+
return this.memoryUpload.array(fieldNames);
|
|
843
|
+
}
|
|
844
|
+
streamUpload(options) {
|
|
845
|
+
return (req, res) => {
|
|
846
|
+
return new Promise((resolve, reject) => {
|
|
847
|
+
const bb = busboy({
|
|
848
|
+
headers: req.headers,
|
|
849
|
+
limits: options?.limits
|
|
850
|
+
});
|
|
851
|
+
const files = [];
|
|
852
|
+
const fields = {};
|
|
853
|
+
bb.on("file", (fieldName, file, info) => {
|
|
854
|
+
files.push({
|
|
855
|
+
fieldName,
|
|
856
|
+
file,
|
|
857
|
+
filename: info.filename,
|
|
858
|
+
encoding: info.encoding,
|
|
859
|
+
mimeType: info.mimeType
|
|
860
|
+
});
|
|
861
|
+
});
|
|
862
|
+
bb.on("field", (fieldName, val) => {
|
|
863
|
+
fields[fieldName] = val;
|
|
864
|
+
});
|
|
865
|
+
bb.on("finish", () => {
|
|
866
|
+
resolve({ files, fields });
|
|
867
|
+
});
|
|
868
|
+
bb.on("error", (err) => {
|
|
869
|
+
reject(err);
|
|
870
|
+
});
|
|
871
|
+
req.pipe(bb);
|
|
872
|
+
});
|
|
873
|
+
};
|
|
874
|
+
}
|
|
806
875
|
}
|
|
807
876
|
function createSchemaValidationMiddleware(schema) {
|
|
808
877
|
const headersSchema = schema.headers ? normalizeHeadersSchema(schema.headers) : null;
|
|
@@ -1,4 +1,108 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
function normalizeExtensions(ext) {
|
|
3
|
+
if (!ext) return [];
|
|
4
|
+
return (Array.isArray(ext) ? ext : [ext]).map((e) => e.toLowerCase().startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
|
|
5
|
+
}
|
|
6
|
+
function normalizeMimeTypes(mime) {
|
|
7
|
+
if (!mime) return [];
|
|
8
|
+
return (Array.isArray(mime) ? mime : [mime]).map((m) => m.toLowerCase());
|
|
9
|
+
}
|
|
10
|
+
function createFileSchema(options = {}) {
|
|
11
|
+
const extensions = normalizeExtensions(options.ext);
|
|
12
|
+
const mimeTypes = normalizeMimeTypes(options.mimeType);
|
|
13
|
+
const fileSchema = z.object({
|
|
14
|
+
fieldname: z.string(),
|
|
15
|
+
originalname: z.string(),
|
|
16
|
+
encoding: z.string(),
|
|
17
|
+
mimetype: z.string(),
|
|
18
|
+
size: z.number(),
|
|
19
|
+
buffer: z.instanceof(Buffer).optional()
|
|
20
|
+
});
|
|
21
|
+
return fileSchema.refine((file) => {
|
|
22
|
+
if (extensions.length === 0) return true;
|
|
23
|
+
const fileExt = file.originalname.toLowerCase().substring(file.originalname.lastIndexOf("."));
|
|
24
|
+
return extensions.includes(fileExt);
|
|
25
|
+
}, {
|
|
26
|
+
message: `Invalid file extension. Allowed: ${extensions.join(", ")}`,
|
|
27
|
+
path: ["originalname"]
|
|
28
|
+
}).refine((file) => {
|
|
29
|
+
if (mimeTypes.length === 0) return true;
|
|
30
|
+
return mimeTypes.includes(file.mimetype.toLowerCase());
|
|
31
|
+
}, {
|
|
32
|
+
message: `Invalid mime type. Allowed: ${mimeTypes.join(", ")}`,
|
|
33
|
+
path: ["mimetype"]
|
|
34
|
+
}).refine((file) => {
|
|
35
|
+
if (options.maxSize === void 0) return true;
|
|
36
|
+
return file.size <= options.maxSize;
|
|
37
|
+
}, {
|
|
38
|
+
message: `File size exceeds maximum of ${options.maxSize} bytes`,
|
|
39
|
+
path: ["size"]
|
|
40
|
+
}).refine((file) => {
|
|
41
|
+
if (options.minSize === void 0) return true;
|
|
42
|
+
return file.size >= options.minSize;
|
|
43
|
+
}, {
|
|
44
|
+
message: `File size must be at least ${options.minSize} bytes`,
|
|
45
|
+
path: ["size"]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function createFilesArraySchema(fieldName, options = {}) {
|
|
49
|
+
const fileSchema = createFileSchema({ ...options });
|
|
50
|
+
return z.array(fileSchema).min(options.required === false ? 0 : 1, {
|
|
51
|
+
message: options.required === false ? void 0 : `At least one file is required for field "${fieldName}"`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const fileValidators = {
|
|
55
|
+
ext: (ext) => {
|
|
56
|
+
const extensions = normalizeExtensions(ext);
|
|
57
|
+
return createFileSchema({ ext: extensions });
|
|
58
|
+
},
|
|
59
|
+
mimeType: (mimeType) => {
|
|
60
|
+
const mimeTypes = normalizeMimeTypes(mimeType);
|
|
61
|
+
return createFileSchema({ mimeType: mimeTypes });
|
|
62
|
+
},
|
|
63
|
+
maxSize: (maxSize) => {
|
|
64
|
+
return createFileSchema({ maxSize });
|
|
65
|
+
},
|
|
66
|
+
minSize: (minSize) => {
|
|
67
|
+
return createFileSchema({ minSize });
|
|
68
|
+
},
|
|
69
|
+
image: () => {
|
|
70
|
+
return createFileSchema({
|
|
71
|
+
mimeType: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
|
|
72
|
+
ext: ["jpg", "jpeg", "png", "gif", "webp", "svg"]
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
document: () => {
|
|
76
|
+
return createFileSchema({
|
|
77
|
+
mimeType: ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "text/plain"],
|
|
78
|
+
ext: ["pdf", "doc", "docx", "txt"]
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
video: () => {
|
|
82
|
+
return createFileSchema({
|
|
83
|
+
mimeType: ["video/mp4", "video/webm", "video/ogg"],
|
|
84
|
+
ext: ["mp4", "webm", "ogg"]
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
audio: () => {
|
|
88
|
+
return createFileSchema({
|
|
89
|
+
mimeType: ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"],
|
|
90
|
+
ext: ["mp3", "wav", "ogg", "webm"]
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
archive: () => {
|
|
94
|
+
return createFileSchema({
|
|
95
|
+
mimeType: ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"],
|
|
96
|
+
ext: ["zip", "rar", "7z"]
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
any: () => {
|
|
100
|
+
return createFileSchema({});
|
|
101
|
+
},
|
|
102
|
+
field: (fieldName, options) => {
|
|
103
|
+
return createFilesArraySchema(fieldName, options);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
2
106
|
function normalizeHeadersSchema(schema) {
|
|
3
107
|
const shape = schema.shape ?? schema._def?.shape?.();
|
|
4
108
|
if (!shape) return schema;
|
|
@@ -23,6 +127,7 @@ Object.assign(sprintCallable, sprintAuth);
|
|
|
23
127
|
const proxyZ = new Proxy(z, {
|
|
24
128
|
get(target, prop) {
|
|
25
129
|
if (prop === "sprint") return sprintCallable;
|
|
130
|
+
if (prop === "files") return fileValidators;
|
|
26
131
|
return target[prop];
|
|
27
132
|
}
|
|
28
133
|
});
|
|
@@ -41,6 +146,7 @@ function parseSchema(schema, data) {
|
|
|
41
146
|
}
|
|
42
147
|
function defineRouteSchema(schema) {
|
|
43
148
|
const headersSchema = schema.headers ? normalizeHeadersSchema(schema.headers) : null;
|
|
149
|
+
const fileConfig = typeof schema.files === "object" && "field" in schema.files ? schema.files : null;
|
|
44
150
|
const middleware = (req, res, next) => {
|
|
45
151
|
const errors = [];
|
|
46
152
|
const method = req.method.toUpperCase();
|
|
@@ -62,6 +168,24 @@ function defineRouteSchema(schema) {
|
|
|
62
168
|
const result = headersSchema.safeParse(normalizedHeaders);
|
|
63
169
|
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "headers", ...e })));
|
|
64
170
|
}
|
|
171
|
+
let filesData = [];
|
|
172
|
+
if (schema.files) {
|
|
173
|
+
if (fileConfig) {
|
|
174
|
+
const fieldFiles = req.file ? [req.file] : [];
|
|
175
|
+
const multiFiles = req.files?.[fileConfig.field] || [];
|
|
176
|
+
filesData = [...fieldFiles, ...Array.isArray(multiFiles) ? multiFiles : []];
|
|
177
|
+
if (fileConfig.maxCount && filesData.length > fileConfig.maxCount) errors.push({ location: "files", path: fileConfig.field, message: `Maximum ${fileConfig.maxCount} files allowed` });
|
|
178
|
+
if (fileConfig.schema && filesData.length > 0) {
|
|
179
|
+
const result = parseSchema(fileConfig.schema, filesData);
|
|
180
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
const filesSchema = schema.files;
|
|
184
|
+
const reqFiles = req.files || (req.file ? [req.file] : []);
|
|
185
|
+
const result = parseSchema(filesSchema, reqFiles);
|
|
186
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
65
189
|
if (schema.sprint?.authorization) {
|
|
66
190
|
const authSchema = schema.sprint.authorization;
|
|
67
191
|
const description = authSchema._def?.description;
|
|
@@ -69,9 +193,7 @@ function defineRouteSchema(schema) {
|
|
|
69
193
|
if (description) {
|
|
70
194
|
try {
|
|
71
195
|
const parsed = JSON.parse(description);
|
|
72
|
-
if (parsed.__sprintAuthorization && parsed.sources)
|
|
73
|
-
sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
|
|
74
|
-
}
|
|
196
|
+
if (parsed.__sprintAuthorization && parsed.sources) sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
|
|
75
197
|
} catch {
|
|
76
198
|
}
|
|
77
199
|
}
|
|
@@ -103,10 +225,19 @@ function defineRouteSchema(schema) {
|
|
|
103
225
|
next();
|
|
104
226
|
};
|
|
105
227
|
middleware.__sprintRouteSchema = schema;
|
|
228
|
+
if (fileConfig) {
|
|
229
|
+
middleware.applyFileUpload = function(sprint) {
|
|
230
|
+
if (fileConfig.maxCount) return sprint.uploadFiles(fileConfig.field);
|
|
231
|
+
return sprint.uploadFile(fileConfig.field);
|
|
232
|
+
};
|
|
233
|
+
}
|
|
106
234
|
return middleware;
|
|
107
235
|
}
|
|
108
236
|
export {
|
|
237
|
+
createFileSchema,
|
|
238
|
+
createFilesArraySchema,
|
|
109
239
|
defineRouteSchema,
|
|
240
|
+
fileValidators as files,
|
|
110
241
|
normalizeHeadersSchema,
|
|
111
242
|
sprintBuilder as sprint,
|
|
112
243
|
proxyZ as z
|
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
2
|
import { z, ZodSchema as ZodSchemaType, ZodTypeDef } from 'zod';
|
|
3
|
+
import { FileObject } from './types';
|
|
3
4
|
export type AuthorizationSource = `query:${string}` | `headers:${string}`;
|
|
4
5
|
export interface SprintAuthorizationOptions {
|
|
5
6
|
sources?: AuthorizationSource | AuthorizationSource[];
|
|
6
7
|
}
|
|
8
|
+
export interface FileValidationOptions {
|
|
9
|
+
ext?: string | string[];
|
|
10
|
+
mimeType?: string | string[];
|
|
11
|
+
maxSize?: number;
|
|
12
|
+
minSize?: number;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare function createFileSchema(options?: FileValidationOptions): ZodSchemaType<FileObject, ZodTypeDef, FileObject>;
|
|
16
|
+
declare function createFilesArraySchema(fieldName: string, options?: FileValidationOptions): ZodSchemaType<FileObject[], ZodTypeDef, FileObject[]>;
|
|
17
|
+
declare const fileValidators: {
|
|
18
|
+
ext: (ext: string | string[]) => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
19
|
+
mimeType: (mimeType: string | string[]) => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
20
|
+
maxSize: (maxSize: number) => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
21
|
+
minSize: (minSize: number) => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
22
|
+
image: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
23
|
+
document: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
24
|
+
video: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
25
|
+
audio: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
26
|
+
archive: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
27
|
+
any: () => z.ZodType<FileObject, z.ZodTypeDef, FileObject>;
|
|
28
|
+
field: (fieldName: string, options?: FileValidationOptions) => z.ZodType<FileObject[], z.ZodTypeDef, FileObject[]>;
|
|
29
|
+
};
|
|
7
30
|
export declare function normalizeHeadersSchema(schema: any): any;
|
|
8
31
|
declare function createSprintAuthorizationSchema(options?: SprintAuthorizationOptions): ZodSchemaType<string, ZodTypeDef, string>;
|
|
9
32
|
declare const sprintBuilder: {
|
|
@@ -15,19 +38,29 @@ declare const sprintAuth: {
|
|
|
15
38
|
type SprintCallable = typeof sprintAuth & (() => typeof sprintAuth);
|
|
16
39
|
type ZodWithSprint = typeof z & {
|
|
17
40
|
sprint: SprintCallable;
|
|
41
|
+
files: typeof fileValidators;
|
|
18
42
|
};
|
|
19
43
|
declare const proxyZ: ZodWithSprint;
|
|
20
44
|
export { proxyZ as z };
|
|
21
45
|
export { sprintBuilder as sprint };
|
|
46
|
+
export { fileValidators as files };
|
|
47
|
+
export { createFileSchema, createFilesArraySchema };
|
|
22
48
|
export interface RouteSchemaOptions {
|
|
23
49
|
body?: ZodSchemaType<any, ZodTypeDef, any>;
|
|
24
50
|
queryParams?: ZodSchemaType<any, ZodTypeDef, any>;
|
|
25
51
|
params?: ZodSchemaType<any, ZodTypeDef, any>;
|
|
26
52
|
headers?: ZodSchemaType<any, ZodTypeDef, any>;
|
|
53
|
+
files?: ZodSchemaType<any, ZodTypeDef, any> | {
|
|
54
|
+
field: string;
|
|
55
|
+
maxCount?: number;
|
|
56
|
+
schema?: ZodSchemaType<any, ZodTypeDef, any>;
|
|
57
|
+
};
|
|
27
58
|
sprint?: {
|
|
28
59
|
authorization?: ZodSchemaType<string, ZodTypeDef, string>;
|
|
29
60
|
};
|
|
30
61
|
}
|
|
31
|
-
export declare function defineRouteSchema<T extends RouteSchemaOptions>(schema: T): RequestHandler
|
|
62
|
+
export declare function defineRouteSchema<T extends RouteSchemaOptions>(schema: T): RequestHandler & {
|
|
63
|
+
applyFileUpload?: (sprint: any) => any;
|
|
64
|
+
};
|
|
32
65
|
export type { ZodSchema, ZodMiddlewareOptions } from './types';
|
|
33
66
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,SAAS,IAAI,aAAa,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,8 +5,24 @@ export interface ZodMiddlewareOptions {
|
|
|
5
5
|
queryParams?: ZodSchema;
|
|
6
6
|
params?: ZodSchema;
|
|
7
7
|
headers?: ZodSchema;
|
|
8
|
+
files?: ZodSchema;
|
|
8
9
|
sprint?: {
|
|
9
10
|
authorization?: ZodSchema;
|
|
10
11
|
};
|
|
11
12
|
}
|
|
13
|
+
export interface FileValidationOptions {
|
|
14
|
+
ext?: string | string[];
|
|
15
|
+
mimeType?: string | string[];
|
|
16
|
+
maxSize?: number;
|
|
17
|
+
minSize?: number;
|
|
18
|
+
required?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export type FileObject = {
|
|
21
|
+
fieldname: string;
|
|
22
|
+
originalname: string;
|
|
23
|
+
encoding: string;
|
|
24
|
+
mimetype: string;
|
|
25
|
+
size: number;
|
|
26
|
+
buffer?: Buffer;
|
|
27
|
+
};
|
|
12
28
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,SAAS,CAAC;KAC7B,CAAC;CACL"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,SAAS,CAAC;KAC7B,CAAC;CACL;AAED,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
package/dist/types/sprint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { default as express, Application, Request, Response } from 'express';
|
|
1
2
|
import { Handler, MiddlewareConfig } from './types';
|
|
2
|
-
import { default as express, Application } from 'express';
|
|
3
3
|
export declare const isDevelopment: boolean;
|
|
4
4
|
export declare const isProduction: boolean;
|
|
5
5
|
export declare class Sprint {
|
|
@@ -19,15 +19,17 @@ export declare class Sprint {
|
|
|
19
19
|
private graphql;
|
|
20
20
|
private graphqlSchema;
|
|
21
21
|
private registeredRoutes;
|
|
22
|
+
fileMemoryUploadedLimit: number;
|
|
23
|
+
memoryUpload: any;
|
|
22
24
|
constructor();
|
|
23
25
|
private init;
|
|
24
26
|
private loadDefaults;
|
|
25
27
|
/**
|
|
26
|
-
* Gets all matching middlewares for a given route path, sorted by priority
|
|
28
|
+
* Gets all matching middlewares for a given route path, sorted by priority.
|
|
27
29
|
*/
|
|
28
30
|
private getMiddlewaresForRoute;
|
|
29
31
|
/**
|
|
30
|
-
* Load all middleware files from the middlewares folder
|
|
32
|
+
* Load all middleware files from the middlewares folder.
|
|
31
33
|
*/
|
|
32
34
|
private loadMiddlewares;
|
|
33
35
|
private loadHealthcheck;
|
|
@@ -48,5 +50,23 @@ export declare class Sprint {
|
|
|
48
50
|
use(pathOrHandler: string | Handler | MiddlewareConfig, maybeHandler?: Handler): express.Application;
|
|
49
51
|
setGraphQLSchema(schema: any): void;
|
|
50
52
|
listen(callback?: () => void): void;
|
|
53
|
+
uploadFile(fieldName?: string): any;
|
|
54
|
+
uploadFiles(fieldNames?: string | string[]): any;
|
|
55
|
+
streamUpload(options?: {
|
|
56
|
+
limits?: {
|
|
57
|
+
fileSize?: number;
|
|
58
|
+
files?: number;
|
|
59
|
+
};
|
|
60
|
+
headers?: Record<string, string>;
|
|
61
|
+
}): (req: Request, res: Response) => Promise<{
|
|
62
|
+
files: Array<{
|
|
63
|
+
fieldName: string;
|
|
64
|
+
file: NodeJS.ReadableStream;
|
|
65
|
+
filename: string;
|
|
66
|
+
encoding: string;
|
|
67
|
+
mimeType: string;
|
|
68
|
+
}>;
|
|
69
|
+
fields: Record<string, string>;
|
|
70
|
+
}>;
|
|
51
71
|
}
|
|
52
72
|
//# sourceMappingURL=sprint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprint.d.ts","sourceRoot":"","sources":["../../src/sprint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sprint.d.ts","sourceRoot":"","sources":["../../src/sprint.ts"],"names":[],"mappings":"AAYA,OAAO,OAAO,EAAE,EAAE,WAAW,EAA2C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC3G,OAAO,EAAE,OAAO,EAA+B,gBAAgB,EAAsC,MAAM,SAAS,CAAC;AAcrH,eAAO,MAAM,aAAa,SAAQ,CAAC;AACnC,eAAO,MAAM,YAAY,SAAS,CAAC;AA0CnC,qBAAa,MAAM;IACR,GAAG,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,IAAI,CAAwD;IACpE,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,OAAO,CAcT;IACN,OAAO,CAAC,OAAO,CAcT;IACN,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,gBAAgB,CAIhB;IACD,uBAAuB,EAAE,MAAM,CAAmB;IAClD,YAAY,EAAE,GAAG,CAAC;;YA6JX,IAAI;IAkDlB,OAAO,CAAC,YAAY;IAiDpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;YACW,eAAe;IAkC7B,OAAO,CAAC,eAAe;YAeT,UAAU;YA+GV,YAAY;IAqB1B,OAAO,CAAC,YAAY;IAgCpB,+BAA+B;IAC/B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,mBAAmB;IA+K3B,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,mBAAmB;IA+BpB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAClC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAClC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACrC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACpC,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,gBAAgB,EAAE,YAAY,CAAC,EAAE,OAAO;IAY9E,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAInC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IAgEnC,UAAU,CAAC,SAAS,GAAE,MAAe;IAIrC,WAAW,CAAC,UAAU,GAAE,MAAM,GAAG,MAAM,EAAY;IAKnD,YAAY,CAAC,OAAO,CAAC,EAAE;QAC1B,MAAM,CAAC,EAAE;YACL,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC,IACW,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAG,OAAO,CAAC;QAC1C,KAAK,EAAE,KAAK,CAAC;YACT,SAAS,EAAE,MAAM,CAAC;YAClB,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC;YAC5B,QAAQ,EAAE,MAAM,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;CA0CT"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -106,6 +106,8 @@ export interface SprintOptions {
|
|
|
106
106
|
path?: string;
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
|
+
/** Maximum file size (in bytes) for memory storage uploads. Default: 5MB (5 * 1024 * 1024) */
|
|
110
|
+
fileMemoryUploadedLimit?: number;
|
|
109
111
|
}
|
|
110
112
|
export interface SprintConfig {
|
|
111
113
|
port?: string | number | null;
|
|
@@ -133,6 +135,8 @@ export interface SprintConfig {
|
|
|
133
135
|
path?: string;
|
|
134
136
|
};
|
|
135
137
|
};
|
|
138
|
+
/** Maximum file size (in bytes) for memory storage uploads. Default: 5MB (5 * 1024 * 1024) */
|
|
139
|
+
fileMemoryUploadedLimit?: number;
|
|
136
140
|
}
|
|
137
141
|
export type { NextFunction } from 'express';
|
|
138
142
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,SAAiC,CAAC;AACpD,eAAO,MAAM,SAAS,SAAqC,CAAC;AAE5D,QAAA,IAAI,UAAU,EAAE,MAAM,CAAC;AACvB,QAAA,IAAI,SAAS,EAAE,MAAM,CAAC;AAYtB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,SAAiC,CAAC;AACpD,eAAO,MAAM,SAAS,SAAqC,CAAC;AAE5D,QAAA,IAAI,UAAU,EAAE,MAAM,CAAC;AACvB,QAAA,IAAI,SAAS,EAAE,MAAM,CAAC;AAYtB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAgBxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAS7D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprint-es",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.157",
|
|
4
4
|
"description": "Sprint - Quickly API",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"@types/express": "^5.0.5",
|
|
111
111
|
"axios": "^1.13.2",
|
|
112
|
+
"busboy": "^1.6.0",
|
|
112
113
|
"cors": "^2.8.5",
|
|
113
114
|
"dotenv": "^17.3.1",
|
|
114
115
|
"express": "^5.1.0",
|
|
@@ -125,6 +126,7 @@
|
|
|
125
126
|
"FJRG2007 (https://github.com/FJRG2007)"
|
|
126
127
|
],
|
|
127
128
|
"devDependencies": {
|
|
129
|
+
"@types/busboy": "^1.5.4",
|
|
128
130
|
"@types/cors": "^2.8.19",
|
|
129
131
|
"@types/jest": "^30.0.0",
|
|
130
132
|
"@types/morgan": "^1.9.10",
|