@technomoron/api-server-base 1.0.37 → 1.0.39
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 +131 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +11 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -0
- package/package.json +27 -20
package/README.txt
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
API Server Base
|
|
2
|
+
================
|
|
3
|
+
|
|
4
|
+
Toolkit for building authenticated Express APIs in TypeScript. ApiServer wraps Express with sensible defaults for JSON parsing, cookie handling, CORS, JWT helpers, and a predictable module system.
|
|
5
|
+
|
|
6
|
+
- Easy setup of a Node Express based API server with all the basics covered.
|
|
7
|
+
- The server can be extended and methods related to user authentication, API keys and more can be overridden in the derived class.
|
|
8
|
+
- Create API endpoints that are either public, protected or open API calls that may or may not have an authenticated session for dual behaviour.
|
|
9
|
+
- Standardized request handling (POST, GET, file uploads if enabled and more).
|
|
10
|
+
- Authentication system using JWT or simple API bearer keys, fully customizable by overriding class methods.
|
|
11
|
+
- Unified error handling. Just throw new ApiError(...) in any API callback in order ot emit the correct API response.
|
|
12
|
+
- Create structured, standardized API response as JSON data, containing typed return data, response codes and more.
|
|
13
|
+
|
|
14
|
+
Highlights
|
|
15
|
+
----------
|
|
16
|
+
Strongly typed base classes for servers (ApiServer) and feature modules (ApiModule).
|
|
17
|
+
Consistent request lifecycle with centralized authentication, authorization hook, and tuple based handler responses.
|
|
18
|
+
JWT, cookie, and API key support with overridable extension points.
|
|
19
|
+
No runtime dependencies beyond the Express ecosystem; required packages install automatically.
|
|
20
|
+
Ships ESM and CommonJS builds plus TypeScript declarations for any Node runtime.
|
|
21
|
+
|
|
22
|
+
Installation
|
|
23
|
+
------------
|
|
24
|
+
pnpm add @technomoron/api-server-base
|
|
25
|
+
|
|
26
|
+
All runtime dependencies and `@types/*` packages are bundled with the distribution. The library exports ES modules by default. Consumers that rely on CommonJS can import via the require entry exposed in package.json.
|
|
27
|
+
|
|
28
|
+
Quick Start
|
|
29
|
+
-----------
|
|
30
|
+
import { ApiServer, ApiModule, ApiError } from '@technomoron/api-server-base';
|
|
31
|
+
|
|
32
|
+
class AppServer extends ApiServer {
|
|
33
|
+
async getUser(uid: unknown) {
|
|
34
|
+
return { id: uid, email: 'demo@example.com' };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
filterUser(user: any) {
|
|
38
|
+
return { id: user.id, email: user.email };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class UserModule extends ApiModule<AppServer> {
|
|
43
|
+
constructor() {
|
|
44
|
+
super({ namespace: '/users' });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
defineRoutes() {
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
method: 'get',
|
|
51
|
+
path: '/',
|
|
52
|
+
auth: { type: 'yes', req: 'any' },
|
|
53
|
+
handler: async ({ server, tokenData }) => {
|
|
54
|
+
const user = await server.getUser(tokenData?.uid);
|
|
55
|
+
if (!user) {
|
|
56
|
+
throw new ApiError({ code: 404, message: 'User not found' });
|
|
57
|
+
}
|
|
58
|
+
return [200, server.filterUser(user)];
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const server = new AppServer({
|
|
66
|
+
apiPort: 3101,
|
|
67
|
+
apiHost: '127.0.0.1',
|
|
68
|
+
accessSecret: 'replace-me',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
server.api(new UserModule()).start();
|
|
72
|
+
|
|
73
|
+
Handlers must return a tuple: [statusCode], [statusCode, data], or [statusCode, data, message]. Throw ApiError for predictable failures.
|
|
74
|
+
|
|
75
|
+
Configuration Reference
|
|
76
|
+
-----------------------
|
|
77
|
+
Pass a partial config object to the ApiServer constructor. Defaults cover most values so you can opt in to what you need.
|
|
78
|
+
|
|
79
|
+
apiPort (number, default 3101) Port the Express app listens on.
|
|
80
|
+
apiHost (string, default 'localhost') Bind address.
|
|
81
|
+
apiBasePath (string, default '/api') Prefix applied to every module namespace.
|
|
82
|
+
origins (string array, default empty array) CORS allowlist; empty allows all origins.
|
|
83
|
+
uploadPath (string, default empty string) Enables multer.any() when provided.
|
|
84
|
+
uploadMax (number, default 30 * 1024 * 1024) Maximum upload size in bytes.
|
|
85
|
+
accessSecret (string, default empty string) Required for JWT signing and verification.
|
|
86
|
+
refreshSecret (string, default empty string) Used for refresh tokens if you implement them.
|
|
87
|
+
cookieDomain (string, default '.somewhere-over-the-rainbow.com') Domain applied to auth cookies.
|
|
88
|
+
accessCookie (string, default 'dat') Access token cookie name.
|
|
89
|
+
refreshCookie (string, default 'drt') Refresh token cookie name.
|
|
90
|
+
accessExpiry (number, default 60 * 15) Access token lifetime in seconds.
|
|
91
|
+
refreshExpiry (number, default 30 * 24 * 60 * 60 * 1000) Refresh token lifetime in milliseconds.
|
|
92
|
+
authApi (boolean, default false) Toggle you can use when mounting auth routes.
|
|
93
|
+
devMode (boolean, default false) Custom hook for development only features.
|
|
94
|
+
debug (boolean, default false) When true the server logs inbound requests via dumpRequest.
|
|
95
|
+
|
|
96
|
+
Tip: If you add new configuration fields in downstream projects, extend ApiServerConf and update fillConfig so defaults stay aligned.
|
|
97
|
+
|
|
98
|
+
Request Lifecycle
|
|
99
|
+
-----------------
|
|
100
|
+
1. Express middlewares (express.json, cookie-parser, optional multer) run before your handler.
|
|
101
|
+
2. ApiServer wraps the route inside handle_request, setting currReq and logging when debug is enabled.
|
|
102
|
+
3. authenticate enforces the ApiRoute auth type: none, maybe, or yes. Bearer tokens and the dat cookie are accepted. API key tokens prefixed with apikey- delegate to getApiKey.
|
|
103
|
+
4. authorize runs with the requested auth class (any or admin in the base implementation). Override to connect to your role system.
|
|
104
|
+
5. The handler executes and returns its tuple. Responses are normalized to { code, message, data } JSON.
|
|
105
|
+
6. Errors bubble into the wrapper. ApiError instances respect the provided status codes; other exceptions result in a 500 with text derived from guessExceptionText.
|
|
106
|
+
|
|
107
|
+
Extending the Base Classes
|
|
108
|
+
--------------------------
|
|
109
|
+
Override getApiKey, getUser, authenticateUser, storeToken, getToken, updateToken, deleteToken, and verifyPassword to integrate with your persistence layer.
|
|
110
|
+
Customize filterUser to trim sensitive data before sending it to the client.
|
|
111
|
+
Provide your own authorize method to enforce role based access control using the ApiAuthClass enum.
|
|
112
|
+
Create feature modules by extending ApiModule. Use the optional checkConfig hook to validate prerequisites before routes mount.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
Tooling and Scripts
|
|
116
|
+
-------------------
|
|
117
|
+
npm run build Build CommonJS and ESM outputs (dist/cjs, dist/esm).
|
|
118
|
+
npm run build:cjs Compile using tsconfig/tsconfig.cjs.json.
|
|
119
|
+
npm run build:esm Compile using tsconfig/tsconfig.esm.json.
|
|
120
|
+
npm run lint Run ESLint with the flat config (eslint.config.mjs).
|
|
121
|
+
npm run lintfix Lint and apply autofixes.
|
|
122
|
+
npm run pretty Run Prettier over common source and documentation files.
|
|
123
|
+
npm run cleanbuild Remove dist/, format, lint, and rebuild.
|
|
124
|
+
|
|
125
|
+
Documentation
|
|
126
|
+
-------------
|
|
127
|
+
See docs/ folder.
|
|
128
|
+
|
|
129
|
+
License
|
|
130
|
+
-------
|
|
131
|
+
MIT License (see LICENSE). Copyright 2025 Bjorn Erik Jacobsen / Technomoron
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ApiError = exports.ApiModule = exports.ApiServer = void 0;
|
|
7
|
+
var api_server_base_js_1 = require("./api-server-base.js");
|
|
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");
|
|
10
|
+
Object.defineProperty(exports, "ApiModule", { enumerable: true, get: function () { return api_server_base_js_2.ApiModule; } });
|
|
11
|
+
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return api_server_base_js_2.ApiError; } });
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@technomoron/api-server-base",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39",
|
|
4
4
|
"description": "Api Server Skeleton / Base Class",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cjs/index.js",
|
|
7
|
+
"module": "./dist/esm/index.js",
|
|
8
|
+
"types": "./dist/esm/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
|
-
"
|
|
10
|
-
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/esm/index.d.ts",
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/cjs/index.js"
|
|
14
|
+
}
|
|
11
15
|
},
|
|
12
16
|
"repository": {
|
|
13
17
|
"type": "git",
|
|
@@ -24,30 +28,31 @@
|
|
|
24
28
|
"scrub": "rm -rf ./node_modules/ pnpm-lock.yaml ./dist/",
|
|
25
29
|
"build:cjs": "tsc --project tsconfig/tsconfig.cjs.json",
|
|
26
30
|
"build:esm": "tsc --project tsconfig/tsconfig.esm.json",
|
|
27
|
-
"build": "
|
|
28
|
-
"test": "
|
|
29
|
-
"
|
|
31
|
+
"build": "tsc --project tsconfig/tsconfig.cjs.json && tsc --project tsconfig/tsconfig.esm.json",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest --watch",
|
|
34
|
+
"prepublishOnly": "tsc --project tsconfig/tsconfig.cjs.json && tsc --project tsconfig/tsconfig.esm.json",
|
|
30
35
|
"lint": "eslint --ext .js,.ts,.vue ./",
|
|
31
36
|
"lintfix": "eslint --fix --ext .js,.ts,.vue ./",
|
|
32
|
-
"format": "
|
|
33
|
-
"cleanbuild": "rm -rf ./dist/ &&
|
|
37
|
+
"format": "eslint --fix --ext .js,.ts,.vue ./ && prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\"",
|
|
38
|
+
"cleanbuild": "rm -rf ./dist/ && eslint --fix --ext .js,.ts,.vue ./ && prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\" && tsc --project tsconfig/tsconfig.cjs.json && tsc --project tsconfig/tsconfig.esm.json",
|
|
34
39
|
"pretty": "prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\""
|
|
35
40
|
},
|
|
36
|
-
"
|
|
37
|
-
"cookie-parser": "^1.4.7",
|
|
38
|
-
"cors": "^2.8.5",
|
|
39
|
-
"express": "^4.21.2",
|
|
40
|
-
"jsonwebtoken": "^9.0.2",
|
|
41
|
-
"multer": "^2.0.1",
|
|
41
|
+
"dependencies": {
|
|
42
42
|
"@types/cookie-parser": "^1.4.9",
|
|
43
43
|
"@types/cors": "^2.8.19",
|
|
44
44
|
"@types/express": "^4 || ^5",
|
|
45
45
|
"@types/jsonwebtoken": "^9.0.9",
|
|
46
|
-
"@types/multer": "^1.4.13"
|
|
46
|
+
"@types/multer": "^1.4.13",
|
|
47
|
+
"cookie-parser": "^1.4.7",
|
|
48
|
+
"cors": "^2.8.5",
|
|
49
|
+
"express": "^4.21.2",
|
|
50
|
+
"jsonwebtoken": "^9.0.2",
|
|
51
|
+
"multer": "^2.0.1"
|
|
47
52
|
},
|
|
48
|
-
"dependencies": {},
|
|
49
53
|
"devDependencies": {
|
|
50
54
|
"@types/express-serve-static-core": "^5.0.6",
|
|
55
|
+
"@types/supertest": "^6.0.3",
|
|
51
56
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
|
52
57
|
"@typescript-eslint/parser": "^8.33.0",
|
|
53
58
|
"@vue/eslint-config-prettier": "10.2.0",
|
|
@@ -56,7 +61,9 @@
|
|
|
56
61
|
"eslint-plugin-import": "^2.31.0",
|
|
57
62
|
"eslint-plugin-vue": "^10.1.0",
|
|
58
63
|
"prettier": "^3.5.3",
|
|
59
|
-
"
|
|
64
|
+
"supertest": "^7.1.4",
|
|
65
|
+
"typescript": "^5.8.3",
|
|
66
|
+
"vitest": "^3.2.4"
|
|
60
67
|
},
|
|
61
68
|
"files": [
|
|
62
69
|
"dist/",
|