@expressots/adapter-express 1.6.0 → 1.8.0

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/lib/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
 
2
2
 
3
+ ## [1.8.0](https://github.com/expressots/adapter-express/compare/1.7.0...1.8.0) (2024-08-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * add expressots middleware in decorators ([055ead9](https://github.com/expressots/adapter-express/commit/055ead94334dd5ea735ddf04a16a322d56d566cc))
9
+ * add FileUpload decorator ([a4f62b1](https://github.com/expressots/adapter-express/commit/a4f62b1cd377625c55218069599a7a262493e3f5))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * adjust error msgs and package resolver ([34a0fcd](https://github.com/expressots/adapter-express/commit/34a0fcde6e637130e328733f48130408fa881a67))
15
+ * adjust isExpressoMiddleware function param types ([edc0888](https://github.com/expressots/adapter-express/commit/edc0888489df4c9f33a5b97af0820ce8f90904e9))
16
+ * return message ([32d656e](https://github.com/expressots/adapter-express/commit/32d656ec2b05a807599e428c9bd0389849c2165d))
17
+
18
+
19
+ ### Code Refactoring
20
+
21
+ * bump expresso core deps & remove husky deprecated code ([a9b243f](https://github.com/expressots/adapter-express/commit/a9b243fd35b877c839da2871401574cf30db808e))
22
+ * httpMethod to Method decorator ([5e853a0](https://github.com/expressots/adapter-express/commit/5e853a04358430e9e6f658bf0d0b68b7e2708a24))
23
+ * remove unnecessary comments ([72c4a15](https://github.com/expressots/adapter-express/commit/72c4a157055fffdfbaad19a69ea124ca0eb7fa13))
24
+
25
+ ## [1.7.0](https://github.com/expressots/adapter-express/compare/1.6.0...1.7.0) (2024-07-23)
26
+
27
+
28
+ ### Features
29
+
30
+ * add @Render decorator ([522d6e2](https://github.com/expressots/adapter-express/commit/522d6e27163b1ec638a9d5328fb3bf5f81054c5c))
31
+ * add pug engine support ([a879f96](https://github.com/expressots/adapter-express/commit/a879f9642dccd74a49b9188a25fcd1bbf30eb8ba))
32
+ * bump husky from 9.0.11 to 9.1.1 ([7c1678a](https://github.com/expressots/adapter-express/commit/7c1678abf4a78e52483fff190524c5658dba1100))
33
+ * bump vite from 5.3.3 to 5.3.4 ([86f51a3](https://github.com/expressots/adapter-express/commit/86f51a3f5f920fcc7a760730e877ae830fa574e5))
34
+
35
+
36
+ ### Bug Fixes
37
+
38
+ * add options to ejs and hbs support ([b52ce5c](https://github.com/expressots/adapter-express/commit/b52ce5c3860ea7d859534d96cee030dbc4ffc19c))
39
+
3
40
  ## [1.6.0](https://github.com/expressots/adapter-express/compare/1.5.0...1.6.0) (2024-07-17)
4
41
 
5
42
 
@@ -20,7 +20,7 @@ const inversify_express_server_1 = require("./express-utils/inversify-express-se
20
20
  const ejs_config_1 = require("./render/ejs/ejs.config");
21
21
  const engine_1 = require("./render/engine");
22
22
  const hbs_config_1 = require("./render/handlebars/hbs.config");
23
- const resolve_render_1 = require("./render/resolve-render");
23
+ const pug_config_1 = require("./render/pug/pug.config");
24
24
  /**
25
25
  * The AppExpress class provides methods for configuring and running an Express application.
26
26
  * @class AppExpress
@@ -163,6 +163,9 @@ let AppExpress = class AppExpress extends application_express_base_1.Application
163
163
  case engine_1.Engine.EJS:
164
164
  await (0, ejs_config_1.setEngineEjs)(this.app, this.renderOptions.options);
165
165
  break;
166
+ case engine_1.Engine.PUG:
167
+ await (0, pug_config_1.setEnginePug)(this.app, this.renderOptions.options);
168
+ break;
166
169
  default:
167
170
  throw new Error("Unsupported engine type!");
168
171
  }
@@ -179,7 +182,6 @@ let AppExpress = class AppExpress extends application_express_base_1.Application
179
182
  * @param {EngineOptions} [options] - The configuration options for the view engine
180
183
  */
181
184
  async setEngine(engine, options) {
182
- (0, resolve_render_1.packageResolver)(engine, options);
183
185
  try {
184
186
  if (options) {
185
187
  this.renderOptions = { engine, options };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_ROUTING_ROOT_PATH = exports.NO_CONTROLLERS_FOUND = exports.DUPLICATED_CONTROLLER_NAME = exports.HTTP_VERBS_ENUM = exports.PARAMETER_TYPE = exports.HTTP_CODE_METADATA = exports.METADATA_KEY = exports.TYPE = void 0;
3
+ exports.DEFAULT_ROUTING_ROOT_PATH = exports.NO_CONTROLLERS_FOUND = exports.DUPLICATED_CONTROLLER_NAME = exports.HTTP_VERBS_ENUM = exports.PARAMETER_TYPE = exports.RENDER_METADATA_KEY = exports.HTTP_CODE_METADATA = exports.METADATA_KEY = exports.TYPE = void 0;
4
4
  exports.TYPE = {
5
5
  AuthProvider: Symbol.for("AuthProvider"),
6
6
  Controller: Symbol.for("Controller"),
@@ -17,6 +17,7 @@ exports.HTTP_CODE_METADATA = {
17
17
  statusCode: "inversify-express-utils:statuscode",
18
18
  path: "inversify-express-utils:path",
19
19
  };
20
+ exports.RENDER_METADATA_KEY = Symbol("Render");
20
21
  var PARAMETER_TYPE;
21
22
  (function (PARAMETER_TYPE) {
22
23
  PARAMETER_TYPE[PARAMETER_TYPE["REQUEST"] = 0] = "REQUEST";
@@ -10,11 +10,16 @@ exports.Put = Put;
10
10
  exports.Patch = Patch;
11
11
  exports.Head = Head;
12
12
  exports.Delete = Delete;
13
- exports.httpMethod = httpMethod;
13
+ exports.Method = Method;
14
14
  exports.params = params;
15
+ exports.Render = Render;
16
+ exports.getRenderMetadata = getRenderMetadata;
17
+ exports.FileUpload = FileUpload;
15
18
  require("reflect-metadata");
16
19
  const inversify_1 = require("inversify");
17
20
  const constants_1 = require("./constants");
21
+ const resolver_multer_1 = require("./resolver-multer");
22
+ const core_1 = require("@expressots/core");
18
23
  exports.injectHttpContext = (0, inversify_1.inject)(constants_1.TYPE.HttpContext);
19
24
  /**
20
25
  * Controller decorator to define a new controller
@@ -81,7 +86,7 @@ function Http(code) {
81
86
  * @param middleware array of middleware to be applied to all routes defined in path logic
82
87
  */
83
88
  function All(path, ...middleware) {
84
- return httpMethod("all", path, ...middleware);
89
+ return Method("all", path, ...middleware);
85
90
  }
86
91
  /**
87
92
  * Decorator to allow GET HTTP method
@@ -97,7 +102,7 @@ function Get(path, ...middleware) {
97
102
  * @param middleware array of middleware to be applied to the route
98
103
  */
99
104
  function Post(path, ...middleware) {
100
- return httpMethod("post", path, ...middleware);
105
+ return Method("post", path, ...middleware);
101
106
  }
102
107
  /**
103
108
  * Decorator to allow PUT HTTP method
@@ -121,7 +126,7 @@ function Patch(path, ...middleware) {
121
126
  * @param middleware array of middleware to be applied to the route
122
127
  */
123
128
  function Head(path, ...middleware) {
124
- return httpMethod("head", path, ...middleware);
129
+ return Method("head", path, ...middleware);
125
130
  }
126
131
  /**
127
132
  * Decorator to allow DELETE HTTP method
@@ -187,7 +192,7 @@ function enhancedHttpMethod(method, path, ...middleware) {
187
192
  * @param path route path
188
193
  * @param middleware array of middleware to be applied to the route
189
194
  */
190
- function httpMethod(method, path, ...middleware) {
195
+ function Method(method, path, ...middleware) {
191
196
  return (target, key) => {
192
197
  const metadata = {
193
198
  key,
@@ -301,6 +306,21 @@ function params(type, parameterName) {
301
306
  Reflect.defineMetadata(constants_1.METADATA_KEY.controllerParameter, metadataList, target.constructor);
302
307
  };
303
308
  }
309
+ /**
310
+ * Render decorator to define the template and default data for a route
311
+ * @param template The template to render
312
+ * @param defaultData The default data to pass to the template
313
+ * @returns
314
+ */
315
+ function Render(template, defaultData) {
316
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
317
+ return (target, propertyKey, descriptor) => {
318
+ Reflect.defineMetadata(constants_1.RENDER_METADATA_KEY, { template, defaultData }, target, propertyKey);
319
+ };
320
+ }
321
+ function getRenderMetadata(target, propertyKey) {
322
+ return Reflect.getMetadata(constants_1.RENDER_METADATA_KEY, target, propertyKey) || {};
323
+ }
304
324
  /**
305
325
  * Converts a string value to the specified type.
306
326
  * @param value The value to convert.
@@ -319,3 +339,87 @@ function convertToType(value, type) {
319
339
  }
320
340
  return value;
321
341
  }
342
+ /**
343
+ * File upload decorator to handle file uploads
344
+ * @param options
345
+ * @param multerOptions
346
+ * @default { none: true }
347
+ * @returns MethodDecorator
348
+ */
349
+ function FileUpload(options, multerOptions) {
350
+ const multer = (0, resolver_multer_1.packageResolver)("multer");
351
+ /* eslint-disable @typescript-eslint/no-explicit-any */
352
+ let upload;
353
+ let method = "none";
354
+ if (multer) {
355
+ if (options === undefined) {
356
+ options = { none: true };
357
+ }
358
+ upload = multer(multerOptions);
359
+ method = inferMulterMethod(options);
360
+ }
361
+ return function (target, propertyKey, descriptor) {
362
+ const originalMethod = descriptor.value;
363
+ /* eslint-disable @typescript-eslint/no-explicit-any */
364
+ descriptor.value = function (...args) {
365
+ const req = args[0];
366
+ const res = args[1];
367
+ // const next = args[2] as NextFunction;
368
+ const multerMiddleware = getMulterMiddleware(upload, options, method);
369
+ multerMiddleware(req, res, (err) => {
370
+ if (err) {
371
+ return res.status(400).json({ error: err.message });
372
+ }
373
+ return originalMethod.apply(this, args);
374
+ });
375
+ };
376
+ };
377
+ }
378
+ /**
379
+ * Infer the multer method to use based on the provided options
380
+ * @param options
381
+ * @returns
382
+ */
383
+ function inferMulterMethod(options) {
384
+ const report = new core_1.Report();
385
+ if (options.none)
386
+ return "none";
387
+ if (options.any)
388
+ return "any";
389
+ if (Array.isArray(options))
390
+ return "fields";
391
+ if (options.fieldName && options.maxCount !== undefined)
392
+ return "array";
393
+ if (options.fieldName)
394
+ return "single";
395
+ throw report.error("Invalid options provided for FileUpload.", core_1.StatusCode.InternalServerError, "multer-decorator");
396
+ }
397
+ /**
398
+ * Get the multer middleware based on the method
399
+ * @param upload
400
+ * @param options
401
+ * @param method
402
+ * @returns
403
+ */
404
+ function getMulterMiddleware(upload, options, method) {
405
+ const report = new core_1.Report();
406
+ switch (method) {
407
+ case "single":
408
+ return upload.single(options.fieldName);
409
+ case "array":
410
+ return upload.array(options.fieldName, options.maxCount);
411
+ case "fields": {
412
+ const fieldsOptions = options.map((opt) => ({
413
+ name: opt.fieldName,
414
+ maxCount: opt.maxCount,
415
+ }));
416
+ return upload.fields(fieldsOptions);
417
+ }
418
+ case "none":
419
+ return upload.none();
420
+ case "any":
421
+ return upload.any();
422
+ default:
423
+ throw report.error(`Unsupported Multer method: ${method}`, core_1.StatusCode.InternalServerError, "multer-decorator");
424
+ }
425
+ }
@@ -30,6 +30,7 @@ const base_middleware_1 = require("./base-middleware");
30
30
  const utils_1 = require("./utils");
31
31
  const constants_1 = require("./constants");
32
32
  const httpResponseMessage_1 = require("./httpResponseMessage");
33
+ const decorators_1 = require("./decorators");
33
34
  class InversifyExpressServer {
34
35
  /**
35
36
  * Wrapper for the express server.
@@ -125,22 +126,32 @@ class InversifyExpressServer {
125
126
  const methodMetadata = (0, utils_1.getControllerMethodMetadata)(controller.constructor);
126
127
  const parameterMetadata = (0, utils_1.getControllerParameterMetadata)(controller.constructor);
127
128
  if (controllerMetadata && methodMetadata) {
128
- const controllerMiddleware = this.resolveMidleware(...controllerMetadata.middleware);
129
+ const controllerMiddleware = this.resolveMiddleware(...controllerMetadata.middleware);
129
130
  methodMetadata.forEach((metadata) => {
130
131
  let paramList = [];
131
132
  if (parameterMetadata) {
132
133
  paramList = parameterMetadata[metadata.key] || [];
133
134
  }
134
135
  const handler = this.handlerFactory(controllerMetadata.target.name, metadata.key, paramList);
135
- const routeMiddleware = this.resolveMidleware(...metadata.middleware);
136
+ const routeMiddleware = this.resolveMiddleware(...metadata.middleware);
136
137
  this._router[metadata.method](`${controllerMetadata.path}${metadata.path}`, ...controllerMiddleware, ...routeMiddleware, handler);
137
138
  });
138
139
  }
139
140
  });
140
141
  this._app.use(this._routingConfig.rootPath, this._router);
141
142
  }
142
- resolveMidleware(...middleware) {
143
+ isExpressoMiddleware(middlewareItem) {
144
+ return (typeof middlewareItem === "object" &&
145
+ "use" in middlewareItem &&
146
+ typeof middlewareItem.use === "function");
147
+ }
148
+ resolveMiddleware(...middleware) {
143
149
  return middleware.map((middlewareItem) => {
150
+ if (this.isExpressoMiddleware(middlewareItem)) {
151
+ return (req, res, next) => {
152
+ middlewareItem.use(req, res, next);
153
+ };
154
+ }
144
155
  if (!this._container.isBound(middlewareItem)) {
145
156
  return middlewareItem;
146
157
  }
@@ -182,8 +193,14 @@ class InversifyExpressServer {
182
193
  const httpContext = this._getHttpContext(req);
183
194
  httpContext.container.bind(constants_1.TYPE.HttpContext).toConstantValue(httpContext);
184
195
  // invoke controller's action
185
- const value = await httpContext.container.getNamed(constants_1.TYPE.Controller, controllerName)[key](...args);
186
- if (value instanceof httpResponseMessage_1.HttpResponseMessage) {
196
+ const controller = httpContext.container.getNamed(constants_1.TYPE.Controller, controllerName);
197
+ const value = await controller[key](...args);
198
+ const { template, defaultData } = (0, decorators_1.getRenderMetadata)(controller, key);
199
+ if (template) {
200
+ const data = value || defaultData || {};
201
+ res.render(template, data);
202
+ }
203
+ else if (value instanceof httpResponseMessage_1.HttpResponseMessage) {
187
204
  await this.handleHttpResponseMessage(value, res);
188
205
  }
189
206
  else if ((0, utils_1.instanceOfIHttpActionResult)(value)) {
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.packageResolver = packageResolver;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const core_1 = require("@expressots/core");
6
+ /**
7
+ * Resolve package from the current working directory.
8
+ * @param packageName
9
+ * @param options
10
+ * @returns
11
+ */
12
+ function packageResolver(packageName) {
13
+ const logger = new core_1.Logger();
14
+ try {
15
+ const hasPackage = require.resolve(packageName, {
16
+ paths: [process.cwd()],
17
+ });
18
+ if (hasPackage) {
19
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
20
+ const packageResolved = require(hasPackage);
21
+ if (typeof packageResolved === "function") {
22
+ return packageResolved;
23
+ }
24
+ if (packageResolved.default && typeof packageResolved.default === "function") {
25
+ return packageResolved.default;
26
+ }
27
+ return packageResolved;
28
+ }
29
+ }
30
+ catch (error) {
31
+ logger.warn(`Package [${packageName}] not installed. Please install it using your package manager.`, "package-resolver");
32
+ }
33
+ }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setEngineEjs = setEngineEjs;
4
4
  const path_1 = require("path");
5
+ const resolve_render_1 = require("../resolve-render");
5
6
  /**
6
7
  * Ejs defaults
7
8
  * @type {EjsOptions}
@@ -19,6 +20,7 @@ const EJS_DEFAULTS = {
19
20
  * @param {EjsOptions} [options=EJS_DEFAULTS] - The ejs options
20
21
  */
21
22
  async function setEngineEjs(app, options = EJS_DEFAULTS) {
23
+ (0, resolve_render_1.packageResolver)("ejs");
22
24
  app.set("view engine", options.viewEngine || EJS_DEFAULTS.viewEngine);
23
25
  app.set("views", options.viewsDir || EJS_DEFAULTS.viewsDir);
24
26
  if (Array.isArray(options.viewsDir)) {
@@ -11,4 +11,5 @@ var Engine;
11
11
  (function (Engine) {
12
12
  Engine["HBS"] = "hbs";
13
13
  Engine["EJS"] = "ejs";
14
+ Engine["PUG"] = "pug";
14
15
  })(Engine || (exports.Engine = Engine = {}));
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setEngineHandlebars = setEngineHandlebars;
4
4
  const path_1 = require("path");
5
5
  const core_1 = require("@expressots/core");
6
+ const resolve_render_1 = require("../resolve-render");
6
7
  /**
7
8
  * Handlebars defaults
8
9
  * @type {HandlebarsOptions}
@@ -10,10 +11,14 @@ const core_1 = require("@expressots/core");
10
11
  * @default
11
12
  */
12
13
  const HANDLEBARS_DEFAULTS = {
13
- viewsDir: (0, path_1.join)(process.cwd(), "views"),
14
14
  viewEngine: "hbs",
15
- serverOptions: {},
15
+ viewsDir: (0, path_1.join)(process.cwd(), "views"),
16
+ partialsDir: (0, path_1.join)(process.cwd(), "views/partials"),
16
17
  };
18
+ /**
19
+ * Default partials directory
20
+ */
21
+ const DEFAULT_PARTIALS_DIR = (0, path_1.join)(process.cwd(), "views/partials");
17
22
  /**
18
23
  * Set Handlebars as the view engine
19
24
  * @param {express.Application} app - The express application
@@ -22,19 +27,10 @@ const HANDLEBARS_DEFAULTS = {
22
27
  async function setEngineHandlebars(app, options = HANDLEBARS_DEFAULTS) {
23
28
  const logger = new core_1.Logger();
24
29
  try {
30
+ const hbs = (0, resolve_render_1.packageResolver)("hbs");
31
+ hbs.registerPartials(options.partialsDir || DEFAULT_PARTIALS_DIR);
25
32
  app.set("view engine", options.viewEngine || HANDLEBARS_DEFAULTS.viewEngine);
26
33
  app.set("views", options.viewsDir || HANDLEBARS_DEFAULTS.viewsDir);
27
- if (Array.isArray(options.viewsDir)) {
28
- options.viewsDir.forEach((dir) => {
29
- app.set("views", dir);
30
- });
31
- }
32
- if (options.serverOptions) {
33
- app.locals = {
34
- ...app.locals,
35
- ...options.serverOptions,
36
- };
37
- }
38
34
  }
39
35
  catch (error) {
40
36
  logger.error(error.message, "handlebars-config");
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setEnginePug = setEnginePug;
4
+ const path_1 = require("path");
5
+ const resolve_render_1 = require("../resolve-render");
6
+ /**
7
+ * Pug defaults
8
+ * @type {PugOptions}
9
+ * @constant
10
+ * @default
11
+ */
12
+ const PUG_DEFAULTS = {
13
+ viewEngine: "pug",
14
+ viewsDir: (0, path_1.join)(process.cwd(), "views"),
15
+ };
16
+ /**
17
+ * Set Pug as the view engine
18
+ * @param {express.Application} app - The express application
19
+ * @param {PugOptions} [options=PUG_DEFAULTS] - The pug options
20
+ */
21
+ async function setEnginePug(app, options = PUG_DEFAULTS) {
22
+ (0, resolve_render_1.packageResolver)("pug");
23
+ app.set("view engine", options.viewEngine || PUG_DEFAULTS.viewEngine);
24
+ app.set("views", options.viewsDir || PUG_DEFAULTS.viewsDir);
25
+ }
@@ -14,6 +14,7 @@ export declare const HTTP_CODE_METADATA: {
14
14
  statusCode: string;
15
15
  path: string;
16
16
  };
17
+ export declare const RENDER_METADATA_KEY: unique symbol;
17
18
  export declare enum PARAMETER_TYPE {
18
19
  REQUEST = 0,
19
20
  RESPONSE = 1,
@@ -70,7 +70,7 @@ export declare function Delete(path: string, ...middleware: Array<Middleware>):
70
70
  * @param path route path
71
71
  * @param middleware array of middleware to be applied to the route
72
72
  */
73
- export declare function httpMethod(method: keyof typeof HTTP_VERBS_ENUM, path: string, ...middleware: Array<Middleware>): HandlerDecorator;
73
+ export declare function Method(method: keyof typeof HTTP_VERBS_ENUM, path: string, ...middleware: Array<Middleware>): HandlerDecorator;
74
74
  /**
75
75
  * Parameter decorator to inject the request object
76
76
  * @returns ParameterDecorator
@@ -121,3 +121,62 @@ export declare const principal: () => ParameterDecorator;
121
121
  * @returns ParameterDecorator
122
122
  */
123
123
  export declare function params(type: PARAMETER_TYPE, parameterName?: string): ParameterDecorator;
124
+ /**
125
+ * Render decorator to define the template and default data for a route
126
+ * @param template The template to render
127
+ * @param defaultData The default data to pass to the template
128
+ * @returns
129
+ */
130
+ export declare function Render(template: string, defaultData?: Record<string, unknown>): MethodDecorator;
131
+ export declare function getRenderMetadata(target: object, propertyKey: string | symbol): {
132
+ template?: string;
133
+ defaultData?: Record<string, unknown>;
134
+ };
135
+ export interface StorageEngine {
136
+ _handleFile(req: unknown, file: MulterFile, callback: (error?: Error | null, info?: Partial<MulterFile>) => void): void;
137
+ _removeFile(req: unknown, file: MulterFile, callback: (error: Error | null) => void): void;
138
+ }
139
+ export interface MulterFile {
140
+ fieldname: string;
141
+ originalname: string;
142
+ encoding: string;
143
+ mimetype: string;
144
+ size: number;
145
+ destination?: string;
146
+ filename?: string;
147
+ path?: string;
148
+ buffer?: Buffer;
149
+ }
150
+ export interface MulterLimits {
151
+ fieldNameSize?: number;
152
+ fieldSize?: number;
153
+ fields?: number;
154
+ fileSize?: number;
155
+ files?: number;
156
+ parts?: number;
157
+ headerPairs?: number;
158
+ }
159
+ export interface MulterOptions {
160
+ dest?: string;
161
+ storage?: StorageEngine;
162
+ limits?: MulterLimits;
163
+ fileFilter?: FileFilter;
164
+ }
165
+ export type FileFilterCallback = (error: Error | null, acceptFile: boolean) => void;
166
+ export type FileFilter = (req: unknown, file: MulterFile, callback: FileFilterCallback) => void;
167
+ type FieldOptions = {
168
+ fieldName: string;
169
+ maxCount?: number;
170
+ };
171
+ /**
172
+ * File upload decorator to handle file uploads
173
+ * @param options
174
+ * @param multerOptions
175
+ * @default { none: true }
176
+ * @returns MethodDecorator
177
+ */
178
+ export declare function FileUpload(options?: FieldOptions | Array<FieldOptions> | {
179
+ none?: boolean;
180
+ any?: boolean;
181
+ }, multerOptions?: MulterOptions): MethodDecorator;
182
+ export {};
@@ -12,7 +12,10 @@ interface ConstructorFunction<T = Record<string, unknown>> {
12
12
  prototype: Prototype<T>;
13
13
  }
14
14
  export type DecoratorTarget<T = unknown> = ConstructorFunction<T> | Prototype<T>;
15
- export type Middleware = string | symbol | RequestHandler;
15
+ export interface IExpressoMiddleware {
16
+ use(req: Request, res: Response, next: NextFunction): Promise<void> | void;
17
+ }
18
+ export type Middleware = string | symbol | RequestHandler | IExpressoMiddleware;
16
19
  export type ControllerHandler = (...params: Array<unknown>) => unknown;
17
20
  export type BaseController = Record<string, ControllerHandler>;
18
21
  export interface Controller {
@@ -46,7 +46,8 @@ export declare class InversifyExpressServer {
46
46
  */
47
47
  build(): express.Application;
48
48
  private registerControllers;
49
- private resolveMidleware;
49
+ private isExpressoMiddleware;
50
+ private resolveMiddleware;
50
51
  private copyHeadersTo;
51
52
  private handleHttpResponseMessage;
52
53
  private handlerFactory;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Resolve package from the current working directory.
3
+ * @param packageName
4
+ * @param options
5
+ * @returns
6
+ */
7
+ export declare function packageResolver(packageName: string): any;
@@ -17,7 +17,8 @@ export type RenderOptions = {
17
17
  */
18
18
  export declare enum Engine {
19
19
  HBS = "hbs",
20
- EJS = "ejs"
20
+ EJS = "ejs",
21
+ PUG = "pug"
21
22
  }
22
23
  /**
23
24
  * The configuration options for the view engine.
@@ -8,9 +8,9 @@ import express from "express";
8
8
  *
9
9
  */
10
10
  export type HandlebarsOptions = {
11
- viewsDir?: string | Array<string>;
12
11
  viewEngine?: string;
13
- serverOptions?: unknown;
12
+ viewsDir?: string;
13
+ partialsDir?: string;
14
14
  };
15
15
  /**
16
16
  * Set Handlebars as the view engine
@@ -1,3 +1,4 @@
1
1
  export { EjsOptions as EJS } from "./ejs/ejs.config";
2
2
  export { HandlebarsOptions as HBS } from "./handlebars/hbs.config";
3
+ export { PugOptions as PUG } from "./pug/pug.config";
3
4
  export { Engine } from "./engine";
@@ -0,0 +1,17 @@
1
+ import { Application } from "express";
2
+ /**
3
+ * Pug options
4
+ * @typedef {Object} PugOptions
5
+ * @property {string} viewEngine - The view engine to be used
6
+ * @property {string} viewsDir - The path to the views folder
7
+ */
8
+ export type PugOptions = {
9
+ viewEngine?: string;
10
+ viewsDir?: string;
11
+ };
12
+ /**
13
+ * Set Pug as the view engine
14
+ * @param {express.Application} app - The express application
15
+ * @param {PugOptions} [options=PUG_DEFAULTS] - The pug options
16
+ */
17
+ export declare function setEnginePug(app: Application, options?: PugOptions): Promise<void>;
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expressots/adapter-express",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Expressots - modern, fast, lightweight nodejs web framework (@adapter-express)",
5
5
  "author": "",
6
6
  "main": "./lib/cjs/index.js",
@@ -75,7 +75,7 @@
75
75
  "@codecov/vite-plugin": "^0.0.1-beta.6",
76
76
  "@commitlint/cli": "19.2.1",
77
77
  "@commitlint/config-conventional": "19.2.2",
78
- "@expressots/core": "2.15.0",
78
+ "@expressots/core": "2.16.0",
79
79
  "@release-it/conventional-changelog": "8.0.1",
80
80
  "@types/express": "4.17.21",
81
81
  "@types/node": "20.14.10",
@@ -84,11 +84,11 @@
84
84
  "@vitest/coverage-v8": "2.0.3",
85
85
  "eslint": "8.57.0",
86
86
  "eslint-config-prettier": "9.1.0",
87
- "husky": "9.0.11",
87
+ "husky": "9.1.1",
88
88
  "prettier": "3.3.3",
89
89
  "release-it": "17.6.0",
90
90
  "typescript": "5.5.3",
91
- "vite": "5.3.3",
91
+ "vite": "5.3.4",
92
92
  "vite-tsconfig-paths": "4.3.2",
93
93
  "vitest": "2.0.3"
94
94
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expressots/adapter-express",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Expressots - modern, fast, lightweight nodejs web framework (@adapter-express)",
5
5
  "author": "",
6
6
  "main": "./lib/cjs/index.js",
@@ -75,7 +75,7 @@
75
75
  "@codecov/vite-plugin": "^0.0.1-beta.6",
76
76
  "@commitlint/cli": "19.2.1",
77
77
  "@commitlint/config-conventional": "19.2.2",
78
- "@expressots/core": "2.15.0",
78
+ "@expressots/core": "2.16.0",
79
79
  "@release-it/conventional-changelog": "8.0.1",
80
80
  "@types/express": "4.17.21",
81
81
  "@types/node": "20.14.10",
@@ -84,11 +84,11 @@
84
84
  "@vitest/coverage-v8": "2.0.3",
85
85
  "eslint": "8.57.0",
86
86
  "eslint-config-prettier": "9.1.0",
87
- "husky": "9.0.11",
87
+ "husky": "9.1.1",
88
88
  "prettier": "3.3.3",
89
89
  "release-it": "17.6.0",
90
90
  "typescript": "5.5.3",
91
- "vite": "5.3.3",
91
+ "vite": "5.3.4",
92
92
  "vite-tsconfig-paths": "4.3.2",
93
93
  "vitest": "2.0.3"
94
94
  },