@technomoron/api-server-base 1.0.23 → 1.0.24

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.
@@ -49,13 +49,15 @@ export type ApiRoute = {
49
49
  req: ApiAuthClass;
50
50
  };
51
51
  };
52
- export interface IApiServer {
53
- addRoutes(routes: ApiRoute[]): void;
54
- }
55
- export declare class ApiModule<T extends IApiServer = ApiServer> {
56
- protected server: T;
57
- init(server: T): this;
58
- protected define_routes(): ApiRoute[];
52
+ export declare class ApiModule<T extends ApiServer> {
53
+ server: T;
54
+ namespace: string;
55
+ mountpath: string;
56
+ static defaultNamespace: string;
57
+ constructor(opts?: {
58
+ namespace?: string;
59
+ });
60
+ defineRoutes(): ApiRoute[];
59
61
  }
60
62
  export interface ApiErrorParams {
61
63
  code?: number;
@@ -79,11 +81,11 @@ export interface ApiServerConf {
79
81
  debug?: boolean;
80
82
  accessExpire?: number;
81
83
  refreshExpire?: number;
84
+ apiBasePath?: string;
82
85
  }
83
86
  export declare class ApiServer {
84
87
  app: Application;
85
88
  currReq: ApiRequest | null;
86
- private routerV1;
87
89
  readonly config: ApiServerConf;
88
90
  jwtSign(payload: any, secret: string, expiresInSeconds: number, options?: SignOptions): JwtSignResult;
89
91
  jwtVerify<T>(token: string, secret: string, options?: VerifyOptions): JwtVerifyResult<T>;
@@ -111,6 +113,8 @@ export declare class ApiServer {
111
113
  accessToken?: string;
112
114
  userId?: unknown;
113
115
  }): Promise<number>;
116
+ verifyPassword(password: string, hash: string): Promise<boolean>;
117
+ filterUser<T = any, U = any>(fullUser: T): U;
114
118
  constructor(config: ApiServerConf);
115
119
  guessExceptionText(error: any, defMsg?: string): string;
116
120
  protected authorize(apiReq: ApiRequest, requiredClass: ApiAuthClass): Promise<void>;
@@ -119,8 +123,7 @@ export declare class ApiServer {
119
123
  private verifyJWT;
120
124
  private authenticate;
121
125
  private handle_request;
122
- addRoutes(routes: ApiRoute[]): void;
123
- api<T extends ApiModule<IApiServer>>(ApiModuleClass: new () => T): this;
126
+ api<T extends ApiModule<any>>(module: T): this;
124
127
  dumpRequest(apiReq: ApiRequest): void;
125
128
  }
126
129
  export default ApiServer;
@@ -16,16 +16,16 @@ const express_1 = __importDefault(require("express"));
16
16
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
17
17
  const multer_1 = __importDefault(require("multer"));
18
18
  class ApiModule {
19
- init(server) {
20
- this.server = server;
21
- server.addRoutes(this.define_routes());
22
- return this;
19
+ constructor(opts = {}) {
20
+ this.mountpath = '';
21
+ this.namespace = opts.namespace ?? this.constructor.defaultNamespace ?? '';
23
22
  }
24
- define_routes() {
23
+ defineRoutes() {
25
24
  return [];
26
25
  }
27
26
  }
28
27
  exports.ApiModule = ApiModule;
28
+ ApiModule.defaultNamespace = '';
29
29
  function guess_exception_text(error, defMsg = 'Unknown Error') {
30
30
  const msg = [];
31
31
  if (typeof error === 'string' && error.trim() !== '') {
@@ -141,6 +141,12 @@ class ApiServer {
141
141
  async deleteToken(params) {
142
142
  throw new Error('deleteToken() not implemented');
143
143
  }
144
+ async verifyPassword(password, hash) {
145
+ throw new Error('verifyPassword() not implemented');
146
+ }
147
+ filterUser(fullUser) {
148
+ return fullUser;
149
+ }
144
150
  constructor(config) {
145
151
  this.currReq = null;
146
152
  config.jwtSecret || (config.jwtSecret = '');
@@ -152,15 +158,14 @@ class ApiServer {
152
158
  config.apiPort || (config.apiPort = 3101);
153
159
  config.accessExpire || (config.accessExpire = 60 * 15); // 15 minutes default
154
160
  config.refreshExpire || (config.refreshExpire = 30 * 24 * 60 * 60); // 30 days
161
+ config.apiBasePath ?? (config.apiBasePath = '/api');
155
162
  this.config = config;
156
- this.routerV1 = express_1.default.Router();
157
163
  this.app = (0, express_1.default)();
158
164
  if (config.uploadPath) {
159
165
  const upload = (0, multer_1.default)({ dest: config.uploadPath });
160
166
  this.app.use(upload.any());
161
167
  }
162
168
  this.middlewares();
163
- this.app.use('/api/v1', this.routerV1);
164
169
  // addSwaggerUi(this.app);
165
170
  }
166
171
  guessExceptionText(error, defMsg = 'Unkown Error') {
@@ -319,30 +324,21 @@ class ApiServer {
319
324
  }
320
325
  };
321
326
  }
322
- addRoutes(routes) {
323
- routes.forEach((route) => {
324
- const handler = this.handle_request(route.handler, route.auth);
325
- switch (route.method) {
326
- case 'get':
327
- this.routerV1.get(route.path, handler);
328
- break;
329
- case 'post':
330
- this.routerV1.post(route.path, handler);
331
- break;
332
- case 'put':
333
- this.routerV1.put(route.path, handler);
334
- break;
335
- case 'delete':
336
- this.routerV1.delete(route.path, handler);
337
- break;
338
- default:
339
- throw new Error(`Unsupported method: ${route.method}`);
327
+ api(module) {
328
+ const router = express_1.default.Router();
329
+ module.server = this;
330
+ const base = this.config.apiBasePath ?? '/api';
331
+ const ns = module.namespace;
332
+ const mountPath = `${base}${ns}`;
333
+ module.mountpath = mountPath;
334
+ module.defineRoutes().forEach((r) => {
335
+ const handler = this.handle_request(r.handler, r.auth);
336
+ router[r.method](r.path, handler);
337
+ if (this.config.debug) {
338
+ console.log(`Adding ${mountPath}${r.path} (${r.method.toUpperCase()})`);
340
339
  }
341
340
  });
342
- }
343
- api(ApiModuleClass) {
344
- const moduleInstance = new ApiModuleClass();
345
- moduleInstance.init(this); // docServer should be a valid IApiServer.
341
+ this.app.use(mountPath, router);
346
342
  return this;
347
343
  }
348
344
  dumpRequest(apiReq) {
@@ -49,13 +49,15 @@ export type ApiRoute = {
49
49
  req: ApiAuthClass;
50
50
  };
51
51
  };
52
- export interface IApiServer {
53
- addRoutes(routes: ApiRoute[]): void;
54
- }
55
- export declare class ApiModule<T extends IApiServer = ApiServer> {
56
- protected server: T;
57
- init(server: T): this;
58
- protected define_routes(): ApiRoute[];
52
+ export declare class ApiModule<T extends ApiServer> {
53
+ server: T;
54
+ namespace: string;
55
+ mountpath: string;
56
+ static defaultNamespace: string;
57
+ constructor(opts?: {
58
+ namespace?: string;
59
+ });
60
+ defineRoutes(): ApiRoute[];
59
61
  }
60
62
  export interface ApiErrorParams {
61
63
  code?: number;
@@ -79,11 +81,11 @@ export interface ApiServerConf {
79
81
  debug?: boolean;
80
82
  accessExpire?: number;
81
83
  refreshExpire?: number;
84
+ apiBasePath?: string;
82
85
  }
83
86
  export declare class ApiServer {
84
87
  app: Application;
85
88
  currReq: ApiRequest | null;
86
- private routerV1;
87
89
  readonly config: ApiServerConf;
88
90
  jwtSign(payload: any, secret: string, expiresInSeconds: number, options?: SignOptions): JwtSignResult;
89
91
  jwtVerify<T>(token: string, secret: string, options?: VerifyOptions): JwtVerifyResult<T>;
@@ -111,6 +113,8 @@ export declare class ApiServer {
111
113
  accessToken?: string;
112
114
  userId?: unknown;
113
115
  }): Promise<number>;
116
+ verifyPassword(password: string, hash: string): Promise<boolean>;
117
+ filterUser<T = any, U = any>(fullUser: T): U;
114
118
  constructor(config: ApiServerConf);
115
119
  guessExceptionText(error: any, defMsg?: string): string;
116
120
  protected authorize(apiReq: ApiRequest, requiredClass: ApiAuthClass): Promise<void>;
@@ -119,8 +123,7 @@ export declare class ApiServer {
119
123
  private verifyJWT;
120
124
  private authenticate;
121
125
  private handle_request;
122
- addRoutes(routes: ApiRoute[]): void;
123
- api<T extends ApiModule<IApiServer>>(ApiModuleClass: new () => T): this;
126
+ api<T extends ApiModule<any>>(module: T): this;
124
127
  dumpRequest(apiReq: ApiRequest): void;
125
128
  }
126
129
  export default ApiServer;
@@ -10,15 +10,15 @@ import express from 'express';
10
10
  import jwt from 'jsonwebtoken';
11
11
  import multer from 'multer';
12
12
  export class ApiModule {
13
- init(server) {
14
- this.server = server;
15
- server.addRoutes(this.define_routes());
16
- return this;
13
+ constructor(opts = {}) {
14
+ this.mountpath = '';
15
+ this.namespace = opts.namespace ?? this.constructor.defaultNamespace ?? '';
17
16
  }
18
- define_routes() {
17
+ defineRoutes() {
19
18
  return [];
20
19
  }
21
20
  }
21
+ ApiModule.defaultNamespace = '';
22
22
  function guess_exception_text(error, defMsg = 'Unknown Error') {
23
23
  const msg = [];
24
24
  if (typeof error === 'string' && error.trim() !== '') {
@@ -133,6 +133,12 @@ export class ApiServer {
133
133
  async deleteToken(params) {
134
134
  throw new Error('deleteToken() not implemented');
135
135
  }
136
+ async verifyPassword(password, hash) {
137
+ throw new Error('verifyPassword() not implemented');
138
+ }
139
+ filterUser(fullUser) {
140
+ return fullUser;
141
+ }
136
142
  constructor(config) {
137
143
  this.currReq = null;
138
144
  config.jwtSecret || (config.jwtSecret = '');
@@ -144,15 +150,14 @@ export class ApiServer {
144
150
  config.apiPort || (config.apiPort = 3101);
145
151
  config.accessExpire || (config.accessExpire = 60 * 15); // 15 minutes default
146
152
  config.refreshExpire || (config.refreshExpire = 30 * 24 * 60 * 60); // 30 days
153
+ config.apiBasePath ?? (config.apiBasePath = '/api');
147
154
  this.config = config;
148
- this.routerV1 = express.Router();
149
155
  this.app = express();
150
156
  if (config.uploadPath) {
151
157
  const upload = multer({ dest: config.uploadPath });
152
158
  this.app.use(upload.any());
153
159
  }
154
160
  this.middlewares();
155
- this.app.use('/api/v1', this.routerV1);
156
161
  // addSwaggerUi(this.app);
157
162
  }
158
163
  guessExceptionText(error, defMsg = 'Unkown Error') {
@@ -311,30 +316,21 @@ export class ApiServer {
311
316
  }
312
317
  };
313
318
  }
314
- addRoutes(routes) {
315
- routes.forEach((route) => {
316
- const handler = this.handle_request(route.handler, route.auth);
317
- switch (route.method) {
318
- case 'get':
319
- this.routerV1.get(route.path, handler);
320
- break;
321
- case 'post':
322
- this.routerV1.post(route.path, handler);
323
- break;
324
- case 'put':
325
- this.routerV1.put(route.path, handler);
326
- break;
327
- case 'delete':
328
- this.routerV1.delete(route.path, handler);
329
- break;
330
- default:
331
- throw new Error(`Unsupported method: ${route.method}`);
319
+ api(module) {
320
+ const router = express.Router();
321
+ module.server = this;
322
+ const base = this.config.apiBasePath ?? '/api';
323
+ const ns = module.namespace;
324
+ const mountPath = `${base}${ns}`;
325
+ module.mountpath = mountPath;
326
+ module.defineRoutes().forEach((r) => {
327
+ const handler = this.handle_request(r.handler, r.auth);
328
+ router[r.method](r.path, handler);
329
+ if (this.config.debug) {
330
+ console.log(`Adding ${mountPath}${r.path} (${r.method.toUpperCase()})`);
332
331
  }
333
332
  });
334
- }
335
- api(ApiModuleClass) {
336
- const moduleInstance = new ApiModuleClass();
337
- moduleInstance.init(this); // docServer should be a valid IApiServer.
333
+ this.app.use(mountPath, router);
338
334
  return this;
339
335
  }
340
336
  dumpRequest(apiReq) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technomoron/api-server-base",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Api Server Skeleton / Base Class",
5
5
  "main": "dist/cjs/api-server-base.js",
6
6
  "module": "dist/esm/api-server-base.js",