skyguard-js 1.2.1 → 1.2.3

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.
Files changed (64) hide show
  1. package/README.md +11 -680
  2. package/dist/app.d.ts +14 -9
  3. package/dist/app.js +37 -30
  4. package/dist/http/context.d.ts +115 -0
  5. package/dist/http/context.js +147 -0
  6. package/dist/http/httpAdapter.d.ts +4 -4
  7. package/dist/http/index.d.ts +3 -1
  8. package/dist/http/index.js +5 -1
  9. package/dist/http/logger.d.ts +9 -2
  10. package/dist/http/logger.js +49 -1
  11. package/dist/http/nodeNativeHttp.d.ts +4 -4
  12. package/dist/http/nodeNativeHttp.js +11 -4
  13. package/dist/http/request.d.ts +4 -0
  14. package/dist/http/request.js +8 -0
  15. package/dist/http/response.d.ts +21 -2
  16. package/dist/http/response.js +30 -2
  17. package/dist/http/webHttp.d.ts +19 -0
  18. package/dist/http/webHttp.js +95 -0
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +2 -2
  21. package/dist/middlewares/cors.d.ts +10 -4
  22. package/dist/middlewares/cors.js +35 -18
  23. package/dist/middlewares/csrf.js +33 -33
  24. package/dist/middlewares/index.d.ts +1 -1
  25. package/dist/middlewares/rateLimiter.d.ts +58 -6
  26. package/dist/middlewares/rateLimiter.js +149 -40
  27. package/dist/middlewares/session.js +4 -4
  28. package/dist/parsers/contentParserManager.d.ts +4 -2
  29. package/dist/parsers/contentParserManager.js +22 -3
  30. package/dist/routing/routeResolveFunc.d.ts +10 -0
  31. package/dist/routing/routeResolveFunc.js +21 -0
  32. package/dist/routing/router.d.ts +16 -10
  33. package/dist/routing/router.js +32 -25
  34. package/dist/routing/routerGroup.d.ts +10 -5
  35. package/dist/routing/routerGroup.js +11 -10
  36. package/dist/server/bunRuntimeServer.d.ts +7 -0
  37. package/dist/server/bunRuntimeServer.js +28 -0
  38. package/dist/server/createRuntimeServer.d.ts +4 -0
  39. package/dist/server/createRuntimeServer.js +23 -0
  40. package/dist/server/denoRuntimeServer.d.ts +7 -0
  41. package/dist/server/denoRuntimeServer.js +27 -0
  42. package/dist/server/index.d.ts +7 -0
  43. package/dist/server/index.js +19 -0
  44. package/dist/server/modulePath.d.ts +6 -0
  45. package/dist/server/modulePath.js +18 -0
  46. package/dist/server/nodeRuntimeServer.d.ts +7 -0
  47. package/dist/server/nodeRuntimeServer.js +21 -0
  48. package/dist/server/runtimeDetector.d.ts +4 -0
  49. package/dist/server/runtimeDetector.js +15 -0
  50. package/dist/server/types.d.ts +11 -0
  51. package/dist/server/types.js +2 -0
  52. package/dist/sessions/index.d.ts +2 -2
  53. package/dist/storage/storage.d.ts +3 -3
  54. package/dist/storage/storage.js +7 -7
  55. package/dist/storage/types.d.ts +5 -5
  56. package/dist/storage/uploader.d.ts +9 -9
  57. package/dist/storage/uploader.js +62 -62
  58. package/dist/types/index.d.ts +11 -10
  59. package/dist/validators/index.d.ts +2 -2
  60. package/dist/validators/rules/index.d.ts +5 -5
  61. package/dist/validators/validationSchema.js +8 -8
  62. package/package.json +2 -2
  63. package/dist/helpers/http.d.ts +0 -95
  64. package/dist/helpers/http.js +0 -112
@@ -63,7 +63,7 @@ class Uploader {
63
63
  * - If the file field does not exist, it does not error; it only attaches text
64
64
  * fields and continues.
65
65
  * - If present, the file is validated, filtered (optional), stored via the
66
- * configured {@link Storage}, and attached as `request.file`.
66
+ * configured {@link Storage}, and attached as `ctx.req.files`.
67
67
  *
68
68
  * @param fieldName Multipart field name expected to contain a file.
69
69
  * @returns A framework {@link Middleware} to be used in the route pipeline.
@@ -74,22 +74,22 @@ class Uploader {
74
74
  * - INVALID_FILE_TYPE if rejected by the filter
75
75
  */
76
76
  single(fieldName) {
77
- return async (request, next) => {
78
- const multipartData = this.getMultipartData(request);
77
+ return async (context, next) => {
78
+ const multipartData = this.getMultipartData(context);
79
79
  if (!multipartData)
80
- return await next(request);
80
+ return await next(context);
81
81
  this.validateFieldLimits(multipartData);
82
82
  const fileData = multipartData.files.find(f => f.fieldName === fieldName);
83
83
  if (!fileData) {
84
- this.attachFieldsToRequest(request, multipartData);
85
- return await next(request);
84
+ this.attachFieldsToRequest(context, multipartData);
85
+ return await next(context);
86
86
  }
87
87
  this.validateFileSize(fileData);
88
- await this.applyFileFilter(request, fileData);
89
- const file = await this.processFile(request, fileData);
90
- request.files = file;
91
- this.attachFieldsToRequest(request, multipartData);
92
- return await next(request);
88
+ await this.applyFileFilter(context, fileData);
89
+ const file = await this.processFile(context, fileData);
90
+ context.req.files = file;
91
+ this.attachFieldsToRequest(context, multipartData);
92
+ return await next(context);
93
93
  };
94
94
  }
95
95
  /**
@@ -97,11 +97,11 @@ class Uploader {
97
97
  *
98
98
  * Behavior:
99
99
  * - If no multipart payload is present, it passes through.
100
- * - If no files exist for the given field, it sets `request.files = []`,
100
+ * - If no files exist for the given field, it sets `ctx.req.files = []`,
101
101
  * attaches text fields, and continues.
102
102
  * - If the number of files exceeds `maxCount`, it throws.
103
103
  * - Each file is validated, filtered (optional), stored, and collected into
104
- * `request.files` as an array of {@link UploadedFile}.
104
+ * `ctx.req.files` as an array of {@link UploadedFile}.
105
105
  *
106
106
  * @param fieldName Multipart field name expected to contain files.
107
107
  * @param maxCount Maximum number of files allowed for this field.
@@ -114,16 +114,16 @@ class Uploader {
114
114
  * - INVALID_FILE_TYPE if any file is rejected by the filter
115
115
  */
116
116
  array(fieldName, maxCount = 10) {
117
- return async (request, next) => {
118
- const multipartData = this.getMultipartData(request);
117
+ return async (context, next) => {
118
+ const multipartData = this.getMultipartData(context);
119
119
  if (!multipartData)
120
- return await next(request);
120
+ return await next(context);
121
121
  this.validateFieldLimits(multipartData);
122
122
  const filesData = multipartData.files.filter(file => file.fieldName === fieldName);
123
123
  if (filesData.length === 0) {
124
- request.files = [];
125
- this.attachFieldsToRequest(request, multipartData);
126
- return await next(request);
124
+ context.req.files = [];
125
+ this.attachFieldsToRequest(context, multipartData);
126
+ return await next(context);
127
127
  }
128
128
  if (filesData.length > maxCount) {
129
129
  throw new uploadException_1.UploadException(`Too many files. Expected max ${maxCount} but got ${filesData.length}`, types_1.UploadErrorCode.LIMIT_FILE_COUNT, fieldName);
@@ -131,12 +131,12 @@ class Uploader {
131
131
  const files = [];
132
132
  for (const fileData of filesData) {
133
133
  this.validateFileSize(fileData);
134
- await this.applyFileFilter(request, fileData);
135
- files.push(await this.processFile(request, fileData));
134
+ await this.applyFileFilter(context, fileData);
135
+ files.push(await this.processFile(context, fileData));
136
136
  }
137
- request.files = files;
138
- this.attachFieldsToRequest(request, multipartData);
139
- return await next(request);
137
+ context.req.files = files;
138
+ this.attachFieldsToRequest(context, multipartData);
139
+ return await next(context);
140
140
  };
141
141
  }
142
142
  /**
@@ -145,7 +145,7 @@ class Uploader {
145
145
  * Behavior:
146
146
  * - Rejects any file whose field name is not declared in `fields`.
147
147
  * - Enforces `maxCount` per declared field (defaults to 1).
148
- * - Aggregates results as `request.files` in a map:
148
+ * - Aggregates results as `ctx.req.files` in a map:
149
149
  * `{ [fieldName]: UploadedFile[] }`.
150
150
  *
151
151
  * @param fields List of allowed fields and their per-field maximum counts.
@@ -159,10 +159,10 @@ class Uploader {
159
159
  * - INVALID_FILE_TYPE if rejected by the filter
160
160
  */
161
161
  fields(fields) {
162
- return async (request, next) => {
163
- const multipartData = this.getMultipartData(request);
162
+ return async (context, next) => {
163
+ const multipartData = this.getMultipartData(context);
164
164
  if (!multipartData)
165
- return await next(request);
165
+ return await next(context);
166
166
  this.validateFieldLimits(multipartData);
167
167
  const filesMap = {};
168
168
  const fieldMap = new Map(fields.map(field => [field.name, field.maxCount || 1]));
@@ -176,12 +176,12 @@ class Uploader {
176
176
  throw new uploadException_1.UploadException(`Too many files for field "${fileData.fieldName}". Max ${maxCount}`, types_1.UploadErrorCode.LIMIT_FILE_COUNT, fileData.fieldName);
177
177
  }
178
178
  this.validateFileSize(fileData);
179
- await this.applyFileFilter(request, fileData);
180
- filesMap[fileData.fieldName].push(await this.processFile(request, fileData));
179
+ await this.applyFileFilter(context, fileData);
180
+ filesMap[fileData.fieldName].push(await this.processFile(context, fileData));
181
181
  }
182
- request.files = filesMap;
183
- this.attachFieldsToRequest(request, multipartData);
184
- return await next(request);
182
+ context.req.files = filesMap;
183
+ this.attachFieldsToRequest(context, multipartData);
184
+ return await next(context);
185
185
  };
186
186
  }
187
187
  /**
@@ -189,7 +189,7 @@ class Uploader {
189
189
  *
190
190
  * Behavior:
191
191
  * - Enforces the global total file limit: `limits.files`.
192
- * - Stores all files and attaches them as `request.files` (array).
192
+ * - Stores all files and attaches them as `ctx.req.files` (array).
193
193
  *
194
194
  * @returns A framework {@link Middleware}.
195
195
  *
@@ -200,22 +200,22 @@ class Uploader {
200
200
  * - INVALID_FILE_TYPE if rejected by the filter
201
201
  */
202
202
  any() {
203
- return async (request, next) => {
204
- const multipartData = this.getMultipartData(request);
203
+ return async (context, next) => {
204
+ const multipartData = this.getMultipartData(context);
205
205
  if (!multipartData)
206
- return await next(request);
206
+ return await next(context);
207
207
  this.validateFieldLimits(multipartData);
208
208
  if (multipartData.files.length > this.limits.files)
209
209
  throw new uploadException_1.UploadException(`Too many files. Max ${this.limits.files}`, types_1.UploadErrorCode.LIMIT_FILE_COUNT);
210
210
  const files = [];
211
211
  for (const fileData of multipartData.files) {
212
212
  this.validateFileSize(fileData);
213
- await this.applyFileFilter(request, fileData);
214
- files.push(await this.processFile(request, fileData));
213
+ await this.applyFileFilter(context, fileData);
214
+ files.push(await this.processFile(context, fileData));
215
215
  }
216
- request.files = files;
217
- this.attachFieldsToRequest(request, multipartData);
218
- return await next(request);
216
+ context.req.files = files;
217
+ this.attachFieldsToRequest(context, multipartData);
218
+ return await next(context);
219
219
  };
220
220
  }
221
221
  /**
@@ -231,15 +231,15 @@ class Uploader {
231
231
  * - LIMIT_UNEXPECTED_FILE if at least one file is received
232
232
  */
233
233
  none() {
234
- return async (request, next) => {
235
- const multipartData = this.getMultipartData(request);
234
+ return async (context, next) => {
235
+ const multipartData = this.getMultipartData(context);
236
236
  if (!multipartData)
237
- return await next(request);
237
+ return await next(context);
238
238
  if (multipartData.files.length > 0) {
239
239
  throw new uploadException_1.UploadException("No files expected", types_1.UploadErrorCode.LIMIT_UNEXPECTED_FILE, multipartData.files[0].fieldName);
240
240
  }
241
- this.attachFieldsToRequest(request, multipartData);
242
- return await next(request);
241
+ this.attachFieldsToRequest(context, multipartData);
242
+ return await next(context);
243
243
  };
244
244
  }
245
245
  /**
@@ -249,14 +249,14 @@ class Uploader {
249
249
  * @param fileData File descriptor from {@link MultipartData}.
250
250
  * @returns The stored file metadata returned by the storage engine.
251
251
  */
252
- async processFile(request, fileData) {
252
+ async processFile(context, fileData) {
253
253
  const partialFile = {
254
254
  fieldName: fileData.fieldName,
255
255
  originalname: fileData.filename,
256
256
  mimetype: fileData.mimetype,
257
257
  size: fileData.size,
258
258
  };
259
- return await this.storage.handleFile(request, partialFile, fileData.data);
259
+ return await this.storage.handleFile(context, partialFile, fileData.data);
260
260
  }
261
261
  /**
262
262
  * Extracts multipart data from the request if available.
@@ -264,10 +264,10 @@ class Uploader {
264
264
  * @param request Current HTTP request.
265
265
  * @returns Parsed multipart data or null if not present.
266
266
  */
267
- getMultipartData(request) {
268
- if (request.headers["content-type"] &&
269
- request.headers["content-type"].startsWith("multipart/form-data"))
270
- return request.body;
267
+ getMultipartData(context) {
268
+ if (context.headers["content-type"] &&
269
+ context.headers["content-type"].startsWith("multipart/form-data"))
270
+ return context.body;
271
271
  return null;
272
272
  }
273
273
  /**
@@ -282,7 +282,7 @@ class Uploader {
282
282
  * @throws UploadException when the filter rejects the file
283
283
  * @throws Error when the filter throws or returns an error
284
284
  */
285
- applyFileFilter(request, fileData) {
285
+ applyFileFilter(context, fileData) {
286
286
  if (!this.fileFilter)
287
287
  return Promise.resolve();
288
288
  const partialFile = {
@@ -301,7 +301,7 @@ class Uploader {
301
301
  };
302
302
  // Call the filter; it may use the callback or return a Promise.
303
303
  try {
304
- const result = this.fileFilter(request, partialFile, (error, acceptFile) => {
304
+ const result = this.fileFilter(context, partialFile, (error, acceptFile) => {
305
305
  finish(error, acceptFile);
306
306
  });
307
307
  // If the filter returned a Promise and didn't use the callback,
@@ -349,13 +349,13 @@ class Uploader {
349
349
  * @param req Current HTTP request.
350
350
  * @param multipartData Parsed multipart payload containing text fields.
351
351
  */
352
- attachFieldsToRequest(request, multipartData) {
353
- const currentData = request.body || {};
352
+ attachFieldsToRequest(context, multipartData) {
353
+ const currentData = context.body || {};
354
354
  const newData = {
355
355
  ...currentData,
356
356
  ...multipartData.fields,
357
357
  };
358
- request.setBody(newData);
358
+ context.req.setBody(newData);
359
359
  }
360
360
  /**
361
361
  * Creates a storage engine instance from the selected {@link StorageType}.
@@ -397,10 +397,10 @@ class Uploader {
397
397
  },
398
398
  });
399
399
 
400
- // Asign middleware a route
401
- app.post("/file", (request) => {
402
- return json({ file: request.file });
403
- }, [uploader.single()])
400
+ // Assign middleware to a route
401
+ app.post("/file", [uploader.single("file")], context => {
402
+ return context.json({ file: context.req.files });
403
+ })
404
404
  */
405
405
  const createUploader = (config) => {
406
406
  return new Uploader(config);
@@ -1,18 +1,18 @@
1
- import { Response, Request, HttpMethods } from "../http/index";
1
+ import { Response, Context, HttpMethods } from "../http/index";
2
2
  import { Layer } from "../routing/layer";
3
3
  /**
4
4
  * Route controller function.
5
5
  *
6
6
  * Represents the final endpoint in the execution pipeline.
7
- * Receives a normalized {@link Request} and must return
7
+ * Receives a normalized {@link Context} and must return
8
8
  * a {@link Response}.
9
9
  *
10
10
  * @example
11
- * const handler: RouteHandler = (req) => {
12
- * return Response.json({ message: "Hello world" });
11
+ * const handler: RouteHandler = context => {
12
+ * return context.json({ message: "Hello world" });
13
13
  * };
14
14
  */
15
- export type RouteHandler = (request: Request) => Promise<Response> | Response;
15
+ export type RouteHandler = (context: Context) => Promise<Response> | Response;
16
16
  /**
17
17
  * Internal routing table structure.
18
18
  *
@@ -82,19 +82,20 @@ export type Constructor<T = unknown> = new (...args: unknown[]) => T;
82
82
  *
83
83
  * Can be synchronous or asynchronous.
84
84
  *
85
- * @param request - Current {@link Request} instance
85
+ * @param context - Current {@link Context} instance
86
86
  * @param next - Function that executes the next middleware
87
87
  * or the route handler
88
88
  * @returns A {@link Response} or a Promise resolving to {@link Response}
89
89
  *
90
90
  * @example
91
- * const loggerMiddleware: Middleware = async (request, next) => {
92
- * console.log(request.getMethod, request.getUrl);
91
+ * const loggerMiddleware: Middleware = async (context, next) => {
92
+ * console.log(context.req.method, context.req.url);
93
93
  *
94
- * const response = await next(request);
94
+ * const response = await next(context);
95
95
  * return response;
96
96
  * };
97
97
  *
98
98
  * app.middlewares(loggerMiddleware);
99
99
  */
100
- export type Middleware = (request: Request, next: RouteHandler) => Response | Promise<Response>;
100
+ export type Middleware = (context: Context, next: RouteHandler) => Response | Promise<Response>;
101
+ export type HandlerOrMiddlewares = RouteHandler | Middleware[];
@@ -1,4 +1,4 @@
1
- export { ValidationRule } from "./validationRule";
1
+ export type { ValidationRule } from "./validationRule";
2
2
  export { Validator } from "./validator";
3
3
  export * from "./rules";
4
- export { RuleOptions, ValidationContext, ValidationError, ValidationResult, FieldDefinition, } from "./types";
4
+ export type { RuleOptions, ValidationContext, ValidationError, ValidationResult, FieldDefinition, } from "./types";
@@ -1,9 +1,9 @@
1
1
  export { BooleanRule } from "./booleanRule";
2
- export { DateRule, DateRuleOptions } from "./dateRule";
3
- export { NumberRule, NumberRuleOptions } from "./numberRule";
4
- export { StringRule, StringRuleOptions } from "./stringRule";
5
- export { ArrayRule, ArrayRuleOptions } from "./arrayRule";
2
+ export { DateRule, type DateRuleOptions } from "./dateRule";
3
+ export { NumberRule, type NumberRuleOptions } from "./numberRule";
4
+ export { StringRule, type StringRuleOptions } from "./stringRule";
5
+ export { ArrayRule, type ArrayRuleOptions } from "./arrayRule";
6
6
  export { LiteralRule } from "./literalRule";
7
7
  export { ObjectRule } from "./objectRule";
8
8
  export { UnionRule } from "./unionRule";
9
- export { BigIntRule, BigIntRuleOptions } from "./bigIntRule";
9
+ export { BigIntRule, type BigIntRuleOptions } from "./bigIntRule";
@@ -340,20 +340,20 @@ exports.v = new ValidatorRules();
340
340
  * @param schema - Validation rules mapped by field name
341
341
  */
342
342
  const validateRequest = (schema) => {
343
- return (request, next) => {
343
+ return (context, next) => {
344
344
  if (schema.body) {
345
- const validBody = validator_1.Validator.validateOrFail(request.body, schema.body);
346
- request.setBody(validBody);
345
+ const validBody = validator_1.Validator.validateOrFail(context.body, schema.body);
346
+ context.req.setBody(validBody);
347
347
  }
348
348
  if (schema.params) {
349
- const validParams = validator_1.Validator.validateOrFail(request.params, schema.params);
350
- request.setParams(validParams);
349
+ const validParams = validator_1.Validator.validateOrFail(context.params, schema.params);
350
+ context.req.setParams(validParams);
351
351
  }
352
352
  if (schema.query) {
353
- const validQuery = validator_1.Validator.validateOrFail(request.query, schema.query);
354
- request.setQuery(validQuery);
353
+ const validQuery = validator_1.Validator.validateOrFail(context.query, schema.query);
354
+ context.req.setQuery(validQuery);
355
355
  }
356
- return next(request);
356
+ return next(context);
357
357
  };
358
358
  };
359
359
  exports.validateRequest = validateRequest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skyguard-js",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "A lightweight, dependency-free TypeScript backend framework",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "bugs": {
30
30
  "url": "https://github.com/Pipe930/Skyguard-js/issues"
31
31
  },
32
- "homepage": "https://github.com/Pipe930/Skyguard-js#readme",
32
+ "homepage": "https://pipe930.github.io/skyguard-documentation/",
33
33
  "engines": {
34
34
  "node": ">=22"
35
35
  },
@@ -1,95 +0,0 @@
1
- import { Response } from "../http/response";
2
- /**
3
- * Creates an HTTP response with a JSON body.
4
- *
5
- * @typeParam T - Type of the payload to be serialized.
6
- * @param data - Data to be serialized as JSON.
7
- * @returns A `Response` instance with `Content-Type: application/json`.
8
- *
9
- * @example
10
- * return json({ ok: true, userId: 1 });
11
- */
12
- export declare function json(data: unknown): Response;
13
- /**
14
- * Creates an HTTP response with a plain text body.
15
- *
16
- * @param data - Text to be sent as the response body.
17
- * @returns A `Response` instance with a text-based `Content-Type`.
18
- *
19
- * @example
20
- * return text("Hello world");
21
- */
22
- export declare function text(data: string): Response;
23
- /**
24
- * Creates an HTTP redirect response to the given URL.
25
- *
26
- * @param url - Target URL for the redirection (absolute or relative).
27
- * @returns A `Response` instance configured as a redirect.
28
- *
29
- * @example
30
- * return redirect("/login");
31
- */
32
- export declare function redirect(url: string): Response;
33
- /**
34
- * Returns a file as a downloadable response.
35
- *
36
- * @param path - File system path to the file (relative or absolute, depending on the runtime).
37
- * @param filename - Optional filename suggested to the client for the download.
38
- * @param headers - Optional additional headers to include in the response.
39
- * @returns A `Promise<Response>` ready to be returned by a route handler.
40
- *
41
- * @example
42
- * return await download("./storage/reports/sales.pdf", "report.pdf", {
43
- * "Cache-Control": "no-store",
44
- * });
45
- */
46
- export declare function download(path: string, filename?: string, headers?: Record<string, string>): Promise<Response>;
47
- /**
48
- * Renders a template/view and returns an HTTP response with the generated HTML.
49
- *
50
- * @param view - View identifier or template path, depending on the template system.
51
- * @param params - Context variables available inside the template.
52
- * @param layout - Optional layout name used to wrap the rendered view.
53
- * @returns A `Promise<Response>` containing the rendered HTML.
54
- *
55
- * @example
56
- * return await render("users/profile", { user }, "main");
57
- */
58
- export declare function render(data: string, params?: Record<string, unknown>): Promise<Response>;
59
- /**
60
- * Sends a file as an HTTP response.
61
- *
62
- * This helper is a thin wrapper around `Response.sendFile`, allowing a file
63
- * to be streamed to the client while optionally applying custom headers
64
- * and resolving the file path relative to a root directory.
65
- *
66
- * @param filePath - Path to the file to send.
67
- * @param options - Optional configuration for the file response.
68
- * @param options.headers - Additional HTTP headers to include in the response
69
- * (e.g. `Content-Type`, `Cache-Control`, `Content-Disposition`).
70
- * @param options.root - Base directory used to resolve `filePath`.
71
- * @returns A `Response` object that streams the requested file to the client.
72
- *
73
- * @example
74
- * // Send a file using an absolute path
75
- * const response = await sendFile("/var/www/files/report.pdf", {});
76
- *
77
- * @example
78
- * // Send a file relative to a root directory
79
- * const response = await sendFile("report.pdf", {
80
- * root: "/var/www/files",
81
- * });
82
- *
83
- * @example
84
- * // Send a downloadable file
85
- * const response = await sendFile("report.pdf", {
86
- * root: "/var/www/files",
87
- * headers: {
88
- * "Content-Disposition": "attachment; filename=\"report.pdf\"",
89
- * },
90
- * });
91
- */
92
- export declare function sendFile(filePath: string, options: {
93
- headers?: Record<string, string>;
94
- root?: string;
95
- }): Promise<Response>;
@@ -1,112 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.json = json;
4
- exports.text = text;
5
- exports.redirect = redirect;
6
- exports.download = download;
7
- exports.render = render;
8
- exports.sendFile = sendFile;
9
- const response_1 = require("../http/response");
10
- /**
11
- * Creates an HTTP response with a JSON body.
12
- *
13
- * @typeParam T - Type of the payload to be serialized.
14
- * @param data - Data to be serialized as JSON.
15
- * @returns A `Response` instance with `Content-Type: application/json`.
16
- *
17
- * @example
18
- * return json({ ok: true, userId: 1 });
19
- */
20
- function json(data) {
21
- return response_1.Response.json(data);
22
- }
23
- /**
24
- * Creates an HTTP response with a plain text body.
25
- *
26
- * @param data - Text to be sent as the response body.
27
- * @returns A `Response` instance with a text-based `Content-Type`.
28
- *
29
- * @example
30
- * return text("Hello world");
31
- */
32
- function text(data) {
33
- return response_1.Response.text(data);
34
- }
35
- /**
36
- * Creates an HTTP redirect response to the given URL.
37
- *
38
- * @param url - Target URL for the redirection (absolute or relative).
39
- * @returns A `Response` instance configured as a redirect.
40
- *
41
- * @example
42
- * return redirect("/login");
43
- */
44
- function redirect(url) {
45
- return response_1.Response.redirect(url);
46
- }
47
- /**
48
- * Returns a file as a downloadable response.
49
- *
50
- * @param path - File system path to the file (relative or absolute, depending on the runtime).
51
- * @param filename - Optional filename suggested to the client for the download.
52
- * @param headers - Optional additional headers to include in the response.
53
- * @returns A `Promise<Response>` ready to be returned by a route handler.
54
- *
55
- * @example
56
- * return await download("./storage/reports/sales.pdf", "report.pdf", {
57
- * "Cache-Control": "no-store",
58
- * });
59
- */
60
- async function download(path, filename, headers) {
61
- return await response_1.Response.download(path, filename, headers);
62
- }
63
- /**
64
- * Renders a template/view and returns an HTTP response with the generated HTML.
65
- *
66
- * @param view - View identifier or template path, depending on the template system.
67
- * @param params - Context variables available inside the template.
68
- * @param layout - Optional layout name used to wrap the rendered view.
69
- * @returns A `Promise<Response>` containing the rendered HTML.
70
- *
71
- * @example
72
- * return await render("users/profile", { user }, "main");
73
- */
74
- async function render(data, params) {
75
- return await response_1.Response.render(data, params);
76
- }
77
- /**
78
- * Sends a file as an HTTP response.
79
- *
80
- * This helper is a thin wrapper around `Response.sendFile`, allowing a file
81
- * to be streamed to the client while optionally applying custom headers
82
- * and resolving the file path relative to a root directory.
83
- *
84
- * @param filePath - Path to the file to send.
85
- * @param options - Optional configuration for the file response.
86
- * @param options.headers - Additional HTTP headers to include in the response
87
- * (e.g. `Content-Type`, `Cache-Control`, `Content-Disposition`).
88
- * @param options.root - Base directory used to resolve `filePath`.
89
- * @returns A `Response` object that streams the requested file to the client.
90
- *
91
- * @example
92
- * // Send a file using an absolute path
93
- * const response = await sendFile("/var/www/files/report.pdf", {});
94
- *
95
- * @example
96
- * // Send a file relative to a root directory
97
- * const response = await sendFile("report.pdf", {
98
- * root: "/var/www/files",
99
- * });
100
- *
101
- * @example
102
- * // Send a downloadable file
103
- * const response = await sendFile("report.pdf", {
104
- * root: "/var/www/files",
105
- * headers: {
106
- * "Content-Disposition": "attachment; filename=\"report.pdf\"",
107
- * },
108
- * });
109
- */
110
- async function sendFile(filePath, options) {
111
- return await response_1.Response.sendFile(filePath, options);
112
- }