sprint-es 0.0.156 → 0.0.159

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.
@@ -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
- this.app.use(finalRoute, ...routeMiddlewares, router);
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
- this.app.use(finalRoute, router);
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,116 @@
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
+ const schemaWithValidations = 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
+ const chainedSchema = Object.create(schemaWithValidations);
50
+ chainedSchema.format = (ext) => createFileSchema({ ...options, ext: normalizeExtensions(ext) });
51
+ chainedSchema.mimeType = (mime) => createFileSchema({ ...options, mimeType: normalizeMimeTypes(mime) });
52
+ chainedSchema.maxSize = (size) => createFileSchema({ ...options, maxSize: size });
53
+ chainedSchema.minSize = (size) => createFileSchema({ ...options, minSize: size });
54
+ return chainedSchema;
55
+ }
56
+ function createFilesArraySchema(fieldName, options = {}) {
57
+ const fileSchema = createFileSchema({ ...options, required: false });
58
+ return zod.z.array(fileSchema).min(options.required === false ? 0 : 1, {
59
+ message: options.required === false ? void 0 : `At least one file is required for field "${fieldName}"`
60
+ });
61
+ }
62
+ const fileValidators = {
63
+ format: (ext) => {
64
+ const extensions = normalizeExtensions(ext);
65
+ return createFileSchema({ ext: extensions });
66
+ },
67
+ mimeType: (mimeType) => {
68
+ const mimeTypes = normalizeMimeTypes(mimeType);
69
+ return createFileSchema({ mimeType: mimeTypes });
70
+ },
71
+ maxSize: (maxSize) => {
72
+ return createFileSchema({ maxSize });
73
+ },
74
+ minSize: (minSize) => {
75
+ return createFileSchema({ minSize });
76
+ },
77
+ image: () => {
78
+ return createFileSchema({
79
+ mimeType: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
80
+ ext: ["jpg", "jpeg", "png", "gif", "webp", "svg"]
81
+ });
82
+ },
83
+ document: () => {
84
+ return createFileSchema({
85
+ mimeType: ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "text/plain"],
86
+ ext: ["pdf", "doc", "docx", "txt"]
87
+ });
88
+ },
89
+ video: () => {
90
+ return createFileSchema({
91
+ mimeType: ["video/mp4", "video/webm", "video/ogg"],
92
+ ext: ["mp4", "webm", "ogg"]
93
+ });
94
+ },
95
+ audio: () => {
96
+ return createFileSchema({
97
+ mimeType: ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"],
98
+ ext: ["mp3", "wav", "ogg", "webm"]
99
+ });
100
+ },
101
+ archive: () => {
102
+ return createFileSchema({
103
+ mimeType: ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"],
104
+ ext: ["zip", "rar", "7z"]
105
+ });
106
+ },
107
+ any: () => {
108
+ return createFileSchema({});
109
+ },
110
+ field: (fieldName, options) => {
111
+ return createFilesArraySchema(fieldName, options);
112
+ }
113
+ };
4
114
  function normalizeHeadersSchema(schema) {
5
115
  const shape = schema.shape ?? schema._def?.shape?.();
6
116
  if (!shape) return schema;
@@ -25,6 +135,7 @@ Object.assign(sprintCallable, sprintAuth);
25
135
  const proxyZ = new Proxy(zod.z, {
26
136
  get(target, prop) {
27
137
  if (prop === "sprint") return sprintCallable;
138
+ if (prop === "files") return fileValidators;
28
139
  return target[prop];
29
140
  }
30
141
  });
@@ -43,6 +154,7 @@ function parseSchema(schema, data) {
43
154
  }
44
155
  function defineRouteSchema(schema) {
45
156
  const headersSchema = schema.headers ? normalizeHeadersSchema(schema.headers) : null;
157
+ const fileConfig = typeof schema.files === "object" && "field" in schema.files ? schema.files : null;
46
158
  const middleware = (req, res, next) => {
47
159
  const errors = [];
48
160
  const method = req.method.toUpperCase();
@@ -64,6 +176,24 @@ function defineRouteSchema(schema) {
64
176
  const result = headersSchema.safeParse(normalizedHeaders);
65
177
  if (!result.success) errors.push(...result.errors.map((e) => ({ location: "headers", ...e })));
66
178
  }
179
+ let filesData = [];
180
+ if (schema.files) {
181
+ if (fileConfig) {
182
+ const fieldFiles = req.file ? [req.file] : [];
183
+ const multiFiles = req.files?.[fileConfig.field] || [];
184
+ filesData = [...fieldFiles, ...Array.isArray(multiFiles) ? multiFiles : []];
185
+ if (fileConfig.maxCount && filesData.length > fileConfig.maxCount) errors.push({ location: "files", path: fileConfig.field, message: `Maximum ${fileConfig.maxCount} files allowed` });
186
+ if (fileConfig.schema && filesData.length > 0) {
187
+ const result = parseSchema(fileConfig.schema, filesData);
188
+ if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
189
+ }
190
+ } else {
191
+ const filesSchema = schema.files;
192
+ const reqFiles = req.files || (req.file ? [req.file] : []);
193
+ const result = parseSchema(filesSchema, reqFiles);
194
+ if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
195
+ }
196
+ }
67
197
  if (schema.sprint?.authorization) {
68
198
  const authSchema = schema.sprint.authorization;
69
199
  const description = authSchema._def?.description;
@@ -71,9 +201,7 @@ function defineRouteSchema(schema) {
71
201
  if (description) {
72
202
  try {
73
203
  const parsed = JSON.parse(description);
74
- if (parsed.__sprintAuthorization && parsed.sources) {
75
- sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
76
- }
204
+ if (parsed.__sprintAuthorization && parsed.sources) sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
77
205
  } catch {
78
206
  }
79
207
  }
@@ -105,9 +233,18 @@ function defineRouteSchema(schema) {
105
233
  next();
106
234
  };
107
235
  middleware.__sprintRouteSchema = schema;
236
+ if (fileConfig) {
237
+ middleware.applyFileUpload = function(sprint) {
238
+ if (fileConfig.maxCount) return sprint.uploadFiles(fileConfig.field);
239
+ return sprint.uploadFile(fileConfig.field);
240
+ };
241
+ }
108
242
  return middleware;
109
243
  }
244
+ exports.createFileSchema = createFileSchema;
245
+ exports.createFilesArraySchema = createFilesArraySchema;
110
246
  exports.defineRouteSchema = defineRouteSchema;
247
+ exports.files = fileValidators;
111
248
  exports.normalizeHeadersSchema = normalizeHeadersSchema;
112
249
  exports.sprint = sprintBuilder;
113
250
  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
- this.app.use(finalRoute, ...routeMiddlewares, router);
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
- this.app.use(finalRoute, router);
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,114 @@
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
+ const schemaWithValidations = 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
+ const chainedSchema = Object.create(schemaWithValidations);
48
+ chainedSchema.format = (ext) => createFileSchema({ ...options, ext: normalizeExtensions(ext) });
49
+ chainedSchema.mimeType = (mime) => createFileSchema({ ...options, mimeType: normalizeMimeTypes(mime) });
50
+ chainedSchema.maxSize = (size) => createFileSchema({ ...options, maxSize: size });
51
+ chainedSchema.minSize = (size) => createFileSchema({ ...options, minSize: size });
52
+ return chainedSchema;
53
+ }
54
+ function createFilesArraySchema(fieldName, options = {}) {
55
+ const fileSchema = createFileSchema({ ...options, required: false });
56
+ return z.array(fileSchema).min(options.required === false ? 0 : 1, {
57
+ message: options.required === false ? void 0 : `At least one file is required for field "${fieldName}"`
58
+ });
59
+ }
60
+ const fileValidators = {
61
+ format: (ext) => {
62
+ const extensions = normalizeExtensions(ext);
63
+ return createFileSchema({ ext: extensions });
64
+ },
65
+ mimeType: (mimeType) => {
66
+ const mimeTypes = normalizeMimeTypes(mimeType);
67
+ return createFileSchema({ mimeType: mimeTypes });
68
+ },
69
+ maxSize: (maxSize) => {
70
+ return createFileSchema({ maxSize });
71
+ },
72
+ minSize: (minSize) => {
73
+ return createFileSchema({ minSize });
74
+ },
75
+ image: () => {
76
+ return createFileSchema({
77
+ mimeType: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
78
+ ext: ["jpg", "jpeg", "png", "gif", "webp", "svg"]
79
+ });
80
+ },
81
+ document: () => {
82
+ return createFileSchema({
83
+ mimeType: ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "text/plain"],
84
+ ext: ["pdf", "doc", "docx", "txt"]
85
+ });
86
+ },
87
+ video: () => {
88
+ return createFileSchema({
89
+ mimeType: ["video/mp4", "video/webm", "video/ogg"],
90
+ ext: ["mp4", "webm", "ogg"]
91
+ });
92
+ },
93
+ audio: () => {
94
+ return createFileSchema({
95
+ mimeType: ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"],
96
+ ext: ["mp3", "wav", "ogg", "webm"]
97
+ });
98
+ },
99
+ archive: () => {
100
+ return createFileSchema({
101
+ mimeType: ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"],
102
+ ext: ["zip", "rar", "7z"]
103
+ });
104
+ },
105
+ any: () => {
106
+ return createFileSchema({});
107
+ },
108
+ field: (fieldName, options) => {
109
+ return createFilesArraySchema(fieldName, options);
110
+ }
111
+ };
2
112
  function normalizeHeadersSchema(schema) {
3
113
  const shape = schema.shape ?? schema._def?.shape?.();
4
114
  if (!shape) return schema;
@@ -23,6 +133,7 @@ Object.assign(sprintCallable, sprintAuth);
23
133
  const proxyZ = new Proxy(z, {
24
134
  get(target, prop) {
25
135
  if (prop === "sprint") return sprintCallable;
136
+ if (prop === "files") return fileValidators;
26
137
  return target[prop];
27
138
  }
28
139
  });
@@ -41,6 +152,7 @@ function parseSchema(schema, data) {
41
152
  }
42
153
  function defineRouteSchema(schema) {
43
154
  const headersSchema = schema.headers ? normalizeHeadersSchema(schema.headers) : null;
155
+ const fileConfig = typeof schema.files === "object" && "field" in schema.files ? schema.files : null;
44
156
  const middleware = (req, res, next) => {
45
157
  const errors = [];
46
158
  const method = req.method.toUpperCase();
@@ -62,6 +174,24 @@ function defineRouteSchema(schema) {
62
174
  const result = headersSchema.safeParse(normalizedHeaders);
63
175
  if (!result.success) errors.push(...result.errors.map((e) => ({ location: "headers", ...e })));
64
176
  }
177
+ let filesData = [];
178
+ if (schema.files) {
179
+ if (fileConfig) {
180
+ const fieldFiles = req.file ? [req.file] : [];
181
+ const multiFiles = req.files?.[fileConfig.field] || [];
182
+ filesData = [...fieldFiles, ...Array.isArray(multiFiles) ? multiFiles : []];
183
+ if (fileConfig.maxCount && filesData.length > fileConfig.maxCount) errors.push({ location: "files", path: fileConfig.field, message: `Maximum ${fileConfig.maxCount} files allowed` });
184
+ if (fileConfig.schema && filesData.length > 0) {
185
+ const result = parseSchema(fileConfig.schema, filesData);
186
+ if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
187
+ }
188
+ } else {
189
+ const filesSchema = schema.files;
190
+ const reqFiles = req.files || (req.file ? [req.file] : []);
191
+ const result = parseSchema(filesSchema, reqFiles);
192
+ if (!result.success) errors.push(...result.errors.map((e) => ({ location: "files", ...e })));
193
+ }
194
+ }
65
195
  if (schema.sprint?.authorization) {
66
196
  const authSchema = schema.sprint.authorization;
67
197
  const description = authSchema._def?.description;
@@ -69,9 +199,7 @@ function defineRouteSchema(schema) {
69
199
  if (description) {
70
200
  try {
71
201
  const parsed = JSON.parse(description);
72
- if (parsed.__sprintAuthorization && parsed.sources) {
73
- sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
74
- }
202
+ if (parsed.__sprintAuthorization && parsed.sources) sources = Array.isArray(parsed.sources) ? parsed.sources : [parsed.sources];
75
203
  } catch {
76
204
  }
77
205
  }
@@ -103,10 +231,19 @@ function defineRouteSchema(schema) {
103
231
  next();
104
232
  };
105
233
  middleware.__sprintRouteSchema = schema;
234
+ if (fileConfig) {
235
+ middleware.applyFileUpload = function(sprint) {
236
+ if (fileConfig.maxCount) return sprint.uploadFiles(fileConfig.field);
237
+ return sprint.uploadFile(fileConfig.field);
238
+ };
239
+ }
106
240
  return middleware;
107
241
  }
108
242
  export {
243
+ createFileSchema,
244
+ createFilesArraySchema,
109
245
  defineRouteSchema,
246
+ fileValidators as files,
110
247
  normalizeHeadersSchema,
111
248
  sprintBuilder as sprint,
112
249
  proxyZ as z
@@ -1,9 +1,38 @@
1
1
  import { RequestHandler } from 'express';
2
- import { z, ZodSchema as ZodSchemaType, ZodTypeDef } from 'zod';
2
+ import { z, ZodSchema as ZodSchemaType, ZodTypeDef, ZodType } 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
+ interface FileSchemaType extends ZodType<FileObject, ZodTypeDef, FileObject> {
16
+ format(ext: string | string[]): FileSchemaType;
17
+ mimeType(mimeType: string | string[]): FileSchemaType;
18
+ maxSize(maxSize: number): FileSchemaType;
19
+ minSize(minSize: number): FileSchemaType;
20
+ }
21
+ declare function createFileSchema(options?: FileValidationOptions): FileSchemaType;
22
+ declare function createFilesArraySchema(fieldName: string, options?: FileValidationOptions): ZodSchemaType<FileObject[], ZodTypeDef, FileObject[]>;
23
+ declare const fileValidators: {
24
+ format: (ext: string | string[]) => FileSchemaType;
25
+ mimeType: (mimeType: string | string[]) => FileSchemaType;
26
+ maxSize: (maxSize: number) => FileSchemaType;
27
+ minSize: (minSize: number) => FileSchemaType;
28
+ image: () => FileSchemaType;
29
+ document: () => FileSchemaType;
30
+ video: () => FileSchemaType;
31
+ audio: () => FileSchemaType;
32
+ archive: () => FileSchemaType;
33
+ any: () => FileSchemaType;
34
+ field: (fieldName: string, options?: FileValidationOptions) => z.ZodType<FileObject[], z.ZodTypeDef, FileObject[]>;
35
+ };
7
36
  export declare function normalizeHeadersSchema(schema: any): any;
8
37
  declare function createSprintAuthorizationSchema(options?: SprintAuthorizationOptions): ZodSchemaType<string, ZodTypeDef, string>;
9
38
  declare const sprintBuilder: {
@@ -15,19 +44,29 @@ declare const sprintAuth: {
15
44
  type SprintCallable = typeof sprintAuth & (() => typeof sprintAuth);
16
45
  type ZodWithSprint = typeof z & {
17
46
  sprint: SprintCallable;
47
+ files: typeof fileValidators;
18
48
  };
19
49
  declare const proxyZ: ZodWithSprint;
20
50
  export { proxyZ as z };
21
51
  export { sprintBuilder as sprint };
52
+ export { fileValidators as files };
53
+ export { createFileSchema, createFilesArraySchema };
22
54
  export interface RouteSchemaOptions {
23
55
  body?: ZodSchemaType<any, ZodTypeDef, any>;
24
56
  queryParams?: ZodSchemaType<any, ZodTypeDef, any>;
25
57
  params?: ZodSchemaType<any, ZodTypeDef, any>;
26
58
  headers?: ZodSchemaType<any, ZodTypeDef, any>;
59
+ files?: ZodSchemaType<any, ZodTypeDef, any> | {
60
+ field: string;
61
+ maxCount?: number;
62
+ schema?: ZodSchemaType<any, ZodTypeDef, any>;
63
+ };
27
64
  sprint?: {
28
65
  authorization?: ZodSchemaType<string, ZodTypeDef, string>;
29
66
  };
30
67
  }
31
- export declare function defineRouteSchema<T extends RouteSchemaOptions>(schema: T): RequestHandler;
68
+ export declare function defineRouteSchema<T extends RouteSchemaOptions>(schema: T): RequestHandler & {
69
+ applyFileUpload?: (sprint: any) => any;
70
+ };
32
71
  export type { ZodSchema, ZodMiddlewareOptions } from './types';
33
72
  //# 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,EAAuB,MAAM,KAAK,CAAC;AAErF,MAAM,MAAM,mBAAmB,GAAG,SAAS,MAAM,EAAE,GAAG,WAAW,MAAM,EAAE,CAAC;AAE1E,MAAM,WAAW,0BAA0B;IACvC,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;CACzD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAKvD;AAED,iBAAS,+BAA+B,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAKxH;AAED,QAAA,MAAM,aAAa;;CAElB,CAAC;AAEF,QAAA,MAAM,UAAU;;CAEf,CAAC;AAEF,KAAK,cAAc,GAAG,OAAO,UAAU,GAAG,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAQpE,KAAK,aAAa,GAAG,OAAO,CAAC,GAAG;IAC5B,MAAM,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,QAAA,MAAM,MAAM,EAKN,aAAa,CAAC;AAEpB,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;AACvB,OAAO,EAAE,aAAa,IAAI,MAAM,EAAE,CAAC;AAEnC,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;KAC7D,CAAC;CACL;AAqBD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,cAAc,CA8EzF;AAED,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC"}
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"}
@@ -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":"AASA,OAAO,EAAE,OAAO,EAA+B,gBAAgB,EAAsC,MAAM,SAAS,CAAC;AACrH,OAAO,OAAO,EAAE,EAAE,WAAW,EAAoD,MAAM,SAAS,CAAC;AAejG,eAAO,MAAM,aAAa,SAAQ,CAAC;AACnC,eAAO,MAAM,YAAY,SAAS,CAAC;AA6CnC,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;;YAuJM,IAAI;IAkDlB,OAAO,CAAC,YAAY;IAiDpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;YACW,eAAe;IAkC7B,OAAO,CAAC,eAAe;YAiBT,UAAU;YAmFV,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;CA+D7C"}
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"}
@@ -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,CAoBxE;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"}
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.156",
3
+ "version": "0.0.159",
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,7 +126,9 @@
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",
131
+ "@types/dotenv": "^6.1.1",
129
132
  "@types/jest": "^30.0.0",
130
133
  "@types/morgan": "^1.9.10",
131
134
  "@types/node": "^22.18.7",