@technomoron/api-server-base 1.0.40 → 1.0.42

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/README.txt CHANGED
@@ -92,6 +92,7 @@ refreshExpiry (number, default 30 * 24 * 60 * 60 * 1000) Refresh token lifetime
92
92
  authApi (boolean, default false) Toggle you can use when mounting auth routes.
93
93
  devMode (boolean, default false) Custom hook for development only features.
94
94
  debug (boolean, default false) When true the server logs inbound requests via dumpRequest.
95
+ hydrateGetBody (boolean, default true) Copy query parameters into `req.body` for GET requests; set false if you prefer untouched bodies.
95
96
 
96
97
  Tip: If you add new configuration fields in downstream projects, extend ApiServerConf and update fillConfig so defaults stay aligned.
97
98
 
@@ -44,6 +44,24 @@ function guess_exception_text(error, defMsg = 'Unknown Error') {
44
44
  }
45
45
  return msg.length > 0 ? msg.join(' / ') : defMsg;
46
46
  }
47
+ function isPlainObject(value) {
48
+ return !!value && typeof value === 'object' && !Array.isArray(value);
49
+ }
50
+ function hydrateGetBody(req) {
51
+ if ((req.method ?? '').toUpperCase() !== 'GET') {
52
+ return;
53
+ }
54
+ const query = isPlainObject(req.query) ? req.query : null;
55
+ if (!query || Object.keys(query).length === 0) {
56
+ return;
57
+ }
58
+ const body = isPlainObject(req.body) ? req.body : null;
59
+ if (!body || Object.keys(body).length === 0) {
60
+ req.body = { ...query };
61
+ return;
62
+ }
63
+ req.body = { ...query, ...body };
64
+ }
47
65
  class ApiError extends Error {
48
66
  constructor({ code, message, data, errors }) {
49
67
  const msg = guess_exception_text(message, '[Unknown error (null/undefined)]');
@@ -72,7 +90,8 @@ function fillConfig(config) {
72
90
  accessExpiry: config.accessExpiry ?? 60 * 15,
73
91
  refreshExpiry: config.refreshExpiry ?? 30 * 24 * 60 * 60 * 1000,
74
92
  authApi: config.authApi ?? false,
75
- devMode: config.devMode ?? false
93
+ devMode: config.devMode ?? false,
94
+ hydrateGetBody: config.hydrateGetBody ?? true
76
95
  };
77
96
  }
78
97
  class ApiServer {
@@ -309,6 +328,9 @@ class ApiServer {
309
328
  token: '',
310
329
  tokenData: null
311
330
  });
331
+ if (this.config.hydrateGetBody) {
332
+ hydrateGetBody(apiReq.req);
333
+ }
312
334
  if (this.config.debug) {
313
335
  this.dumpRequest(apiReq);
314
336
  }
@@ -98,6 +98,7 @@ export interface ApiServerConf {
98
98
  refreshExpiry: number;
99
99
  authApi: boolean;
100
100
  devMode: boolean;
101
+ hydrateGetBody: boolean;
101
102
  }
102
103
  export declare class ApiServer {
103
104
  app: Application;
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ApiError = exports.ApiModule = exports.ApiServer = void 0;
7
- var api_server_base_js_1 = require("./api-server-base.js");
7
+ var api_server_base_js_1 = require("./api-server-base.cjs");
8
8
  Object.defineProperty(exports, "ApiServer", { enumerable: true, get: function () { return __importDefault(api_server_base_js_1).default; } });
9
- var api_server_base_js_2 = require("./api-server-base.js");
9
+ var api_server_base_js_2 = require("./api-server-base.cjs");
10
10
  Object.defineProperty(exports, "ApiModule", { enumerable: true, get: function () { return api_server_base_js_2.ApiModule; } });
11
11
  Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return api_server_base_js_2.ApiError; } });
@@ -98,6 +98,7 @@ export interface ApiServerConf {
98
98
  refreshExpiry: number;
99
99
  authApi: boolean;
100
100
  devMode: boolean;
101
+ hydrateGetBody: boolean;
101
102
  }
102
103
  export declare class ApiServer {
103
104
  app: Application;
@@ -37,6 +37,24 @@ function guess_exception_text(error, defMsg = 'Unknown Error') {
37
37
  }
38
38
  return msg.length > 0 ? msg.join(' / ') : defMsg;
39
39
  }
40
+ function isPlainObject(value) {
41
+ return !!value && typeof value === 'object' && !Array.isArray(value);
42
+ }
43
+ function hydrateGetBody(req) {
44
+ if ((req.method ?? '').toUpperCase() !== 'GET') {
45
+ return;
46
+ }
47
+ const query = isPlainObject(req.query) ? req.query : null;
48
+ if (!query || Object.keys(query).length === 0) {
49
+ return;
50
+ }
51
+ const body = isPlainObject(req.body) ? req.body : null;
52
+ if (!body || Object.keys(body).length === 0) {
53
+ req.body = { ...query };
54
+ return;
55
+ }
56
+ req.body = { ...query, ...body };
57
+ }
40
58
  export class ApiError extends Error {
41
59
  constructor({ code, message, data, errors }) {
42
60
  const msg = guess_exception_text(message, '[Unknown error (null/undefined)]');
@@ -64,7 +82,8 @@ function fillConfig(config) {
64
82
  accessExpiry: config.accessExpiry ?? 60 * 15,
65
83
  refreshExpiry: config.refreshExpiry ?? 30 * 24 * 60 * 60 * 1000,
66
84
  authApi: config.authApi ?? false,
67
- devMode: config.devMode ?? false
85
+ devMode: config.devMode ?? false,
86
+ hydrateGetBody: config.hydrateGetBody ?? true
68
87
  };
69
88
  }
70
89
  export class ApiServer {
@@ -301,6 +320,9 @@ export class ApiServer {
301
320
  token: '',
302
321
  tokenData: null
303
322
  });
323
+ if (this.config.hydrateGetBody) {
324
+ hydrateGetBody(apiReq.req);
325
+ }
304
326
  if (this.config.debug) {
305
327
  this.dumpRequest(apiReq);
306
328
  }
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@technomoron/api-server-base",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "description": "Api Server Skeleton / Base Class",
5
5
  "type": "module",
6
- "main": "./dist/cjs/index.js",
6
+ "main": "./dist/cjs/index.cjs",
7
7
  "module": "./dist/esm/index.js",
8
8
  "types": "./dist/esm/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/esm/index.d.ts",
12
12
  "import": "./dist/esm/index.js",
13
- "require": "./dist/cjs/index.js"
13
+ "require": "./dist/cjs/index.cjs"
14
14
  }
15
15
  },
16
16
  "repository": {
@@ -26,12 +26,12 @@
26
26
  "homepage": "https://github.com/technomoron/api-server-base#readme",
27
27
  "scripts": {
28
28
  "scrub": "rm -rf ./node_modules/ pnpm-lock.yaml ./dist/",
29
- "build:cjs": "tsc --project tsconfig/tsconfig.cjs.json",
29
+ "build:cjs": "tsc --project tsconfig/tsconfig.cjs.json && node scripts/prepare-cjs.cjs",
30
30
  "build:esm": "tsc --project tsconfig/tsconfig.esm.json",
31
- "build": "tsc --project tsconfig/tsconfig.cjs.json && tsc --project tsconfig/tsconfig.esm.json",
31
+ "build": "npm run build:cjs && npm run build:esm",
32
32
  "test": "vitest run",
33
33
  "test:watch": "vitest --watch",
34
- "prepublishOnly": "tsc --project tsconfig/tsconfig.cjs.json && tsc --project tsconfig/tsconfig.esm.json",
34
+ "prepublishOnly": "npm run build:cjs && npm run build:esm",
35
35
  "lint": "eslint --ext .js,.ts,.vue ./",
36
36
  "lintfix": "eslint --fix --ext .js,.ts,.vue ./",
37
37
  "format": "eslint --fix --ext .js,.ts,.vue ./ && prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\"",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@types/cookie-parser": "^1.4.9",
43
43
  "@types/cors": "^2.8.19",
44
- "@types/express": "^4 || ^5",
44
+ "@types/express": "^4.17.21",
45
45
  "@types/jsonwebtoken": "^9.0.9",
46
46
  "@types/multer": "^1.4.13",
47
47
  "cookie-parser": "^1.4.7",