@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
|
}
|
|
@@ -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.
|
|
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.
|
|
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; } });
|
|
@@ -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.
|
|
3
|
+
"version": "1.0.42",
|
|
4
4
|
"description": "Api Server Skeleton / Base Class",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/cjs/index.
|
|
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.
|
|
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": "
|
|
31
|
+
"build": "npm run build:cjs && npm run build:esm",
|
|
32
32
|
"test": "vitest run",
|
|
33
33
|
"test:watch": "vitest --watch",
|
|
34
|
-
"prepublishOnly": "
|
|
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
|
|
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",
|