@naiv/flazy-api 0.0.1
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/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/build-from-api.d.ts +5 -0
- package/dist/build-from-api.js +110 -0
- package/dist/build-from-enum.d.ts +4 -0
- package/dist/build-from-enum.js +24 -0
- package/dist/build-from-schema.d.ts +24 -0
- package/dist/build-from-schema.js +207 -0
- package/dist/build-from-table.d.ts +10 -0
- package/dist/build-from-table.js +253 -0
- package/dist/cmd-generate.d.ts +1 -0
- package/dist/cmd-generate.js +46 -0
- package/dist/cmd-run.d.ts +1 -0
- package/dist/cmd-run.js +34 -0
- package/dist/compile-folter.d.ts +4 -0
- package/dist/compile-folter.js +70 -0
- package/dist/data-types.d.ts +11 -0
- package/dist/data-types.js +2 -0
- package/dist/exec.d.ts +2 -0
- package/dist/exec.js +16 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +37 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.js +192 -0
- package/package.json +45 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.Server = void 0;
|
|
49
|
+
require("reflect-metadata");
|
|
50
|
+
const express_1 = __importStar(require("express"));
|
|
51
|
+
const cors_1 = __importDefault(require("cors"));
|
|
52
|
+
const class_transformer_1 = require("class-transformer");
|
|
53
|
+
const class_validator_1 = require("class-validator");
|
|
54
|
+
const path_1 = __importDefault(require("path"));
|
|
55
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
56
|
+
const { createRequire } = require("module");
|
|
57
|
+
const Module = require("module");
|
|
58
|
+
// patch resolver
|
|
59
|
+
const root = path_1.default.resolve(__dirname, "..");
|
|
60
|
+
const nm = path_1.default.join(root, "node_modules");
|
|
61
|
+
Module.globalPaths.push(nm);
|
|
62
|
+
process.env.NODE_PATH = nm;
|
|
63
|
+
Module._initPaths();
|
|
64
|
+
class Server {
|
|
65
|
+
constructor(param) {
|
|
66
|
+
this.express = (0, express_1.default)();
|
|
67
|
+
this.constructor_param = param;
|
|
68
|
+
}
|
|
69
|
+
run(param) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
var _a, _b, _c, _d;
|
|
72
|
+
if (!((_a = this.constructor_param) === null || _a === void 0 ? void 0 : _a.noCors)) {
|
|
73
|
+
this.express.use((0, cors_1.default)());
|
|
74
|
+
}
|
|
75
|
+
this.express.use(express_1.default.json({ limit: '5mb' }));
|
|
76
|
+
if (!((_b = this.constructor_param) === null || _b === void 0 ? void 0 : _b.noTrustProxy)) {
|
|
77
|
+
this.express.set('trust proxy', true);
|
|
78
|
+
}
|
|
79
|
+
if (param.beforeStart) {
|
|
80
|
+
yield param.beforeStart();
|
|
81
|
+
}
|
|
82
|
+
yield this._run(param.types_path, param.implementation_path, param.api_prefix);
|
|
83
|
+
const port = (_d = (_c = param === null || param === void 0 ? void 0 : param.port) !== null && _c !== void 0 ? _c : process.env.PORT) !== null && _d !== void 0 ? _d : 3000;
|
|
84
|
+
this.express.listen(port, () => {
|
|
85
|
+
console.log(`\n⚡️[server]: Server is running at http://localhost:${port}`);
|
|
86
|
+
});
|
|
87
|
+
return this;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
errorToString(list_error) {
|
|
91
|
+
return list_error.map(err => {
|
|
92
|
+
const children = err.children;
|
|
93
|
+
if (children && children.length > 0) {
|
|
94
|
+
return this.errorToString(children);
|
|
95
|
+
}
|
|
96
|
+
const constrains = err.constraints;
|
|
97
|
+
const keys = Object.keys(constrains);
|
|
98
|
+
return keys.filter(key => constrains[key].length > 0).map(key => constrains[key]).join(', ');
|
|
99
|
+
}).join(', ');
|
|
100
|
+
}
|
|
101
|
+
_run(types_folder_abs_path_1, implementation_folder_1) {
|
|
102
|
+
return __awaiter(this, arguments, void 0, function* (types_folder_abs_path, implementation_folder, api_prefix = '/') {
|
|
103
|
+
if (!this.express) {
|
|
104
|
+
throw new Error('🚨 ExpressJS has not been initialized yet');
|
|
105
|
+
}
|
|
106
|
+
const router = (0, express_1.Router)();
|
|
107
|
+
const files = yield promises_1.default.readdir(path_1.default.join(types_folder_abs_path, 'api'));
|
|
108
|
+
for (const file of files) {
|
|
109
|
+
const filename_without_ext = path_1.default.basename(file, path_1.default.extname(file));
|
|
110
|
+
const types = require(path_1.default.join(types_folder_abs_path, 'api', filename_without_ext));
|
|
111
|
+
const method = types['method'];
|
|
112
|
+
const url_path = types['url_path'];
|
|
113
|
+
const alias = types['alias'];
|
|
114
|
+
const is_streaming = types['is_streaming'];
|
|
115
|
+
if (!alias) {
|
|
116
|
+
console.warn(`⚠️ api '${method} ${url_path}' doesnt have alias name, skip.`);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
let f;
|
|
120
|
+
try {
|
|
121
|
+
f = require(path_1.default.join(implementation_folder, alias));
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
if (err.code === "MODULE_NOT_FOUND") {
|
|
125
|
+
console.warn(`⚠️ implementation for api '${method} ${url_path}' not found, skip.`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
const export_alias = alias.charAt(0).toLowerCase() + alias.slice(1);
|
|
131
|
+
const fn = f[export_alias];
|
|
132
|
+
if (!fn) {
|
|
133
|
+
console.warn(`⚠️ export function implementation for api '${method} ${url_path}' not found, skip.`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
router[method.toLowerCase()](url_path, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
const t_headers = types[`T_${alias}_headers`];
|
|
138
|
+
const t_query = types[`T_${alias}_query`];
|
|
139
|
+
const t_path = types[`T_${alias}_path`];
|
|
140
|
+
const t_body = types[`T_${alias}_body`];
|
|
141
|
+
try {
|
|
142
|
+
if (t_headers) {
|
|
143
|
+
yield (0, class_validator_1.validateOrReject)((0, class_transformer_1.plainToInstance)(t_headers, req.headers));
|
|
144
|
+
}
|
|
145
|
+
if (t_query) {
|
|
146
|
+
yield (0, class_validator_1.validateOrReject)((0, class_transformer_1.plainToInstance)(t_query, req.query));
|
|
147
|
+
}
|
|
148
|
+
if (t_path) {
|
|
149
|
+
yield (0, class_validator_1.validateOrReject)((0, class_transformer_1.plainToInstance)(t_path, req.params));
|
|
150
|
+
}
|
|
151
|
+
if (t_body) {
|
|
152
|
+
yield (0, class_validator_1.validateOrReject)((0, class_transformer_1.plainToInstance)(t_body, req.body));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (err_validation) {
|
|
156
|
+
res.status(400).send(this.errorToString(err_validation));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const request_params = {
|
|
161
|
+
headers: req.headers,
|
|
162
|
+
query: req.query,
|
|
163
|
+
path: req.params,
|
|
164
|
+
body: req.body,
|
|
165
|
+
};
|
|
166
|
+
if (is_streaming) {
|
|
167
|
+
res.status(200);
|
|
168
|
+
yield fn(request_params, (chunk) => res.write(chunk), res);
|
|
169
|
+
res.end(null);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const result = yield fn(request_params, res);
|
|
173
|
+
res.status(200).json(result);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
const err_msg = err.toString();
|
|
178
|
+
if (/^s*d{3}s*:/.test(err_msg)) {
|
|
179
|
+
const [err_code, msg] = err_msg.split(':');
|
|
180
|
+
res.status(+err_code.trim()).send(msg);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
res.status(500).send(err_msg);
|
|
184
|
+
}
|
|
185
|
+
}));
|
|
186
|
+
console.info(`✅api [${is_streaming ? 'stream' : 'normal'}] '${method} ${url_path}' (${alias}) is ready`);
|
|
187
|
+
}
|
|
188
|
+
this.express.use(api_prefix, router);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.Server = Server;
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@naiv/flazy-api",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rm -rf dist && tsc && npm unlink -g && npm link",
|
|
10
|
+
"start": "node dist",
|
|
11
|
+
"dev": "npm run build && npm start",
|
|
12
|
+
"test": "rm -rf test/api && npm run build && flazy-api -d test -o test"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"flazy-api": "dist/exec.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"package.json"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"description": "",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/axios": "^0.9.36",
|
|
27
|
+
"@types/cors": "^2.8.19",
|
|
28
|
+
"@types/express": "^5.0.3",
|
|
29
|
+
"@types/lodash": "^4.17.13",
|
|
30
|
+
"@types/node": "^22.8.1",
|
|
31
|
+
"typescript": "^5.6.3"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@naiv/core": "^0.0.15",
|
|
35
|
+
"arg": "^5.0.2",
|
|
36
|
+
"class-transformer": "^0.5.1",
|
|
37
|
+
"class-validator": "^0.14.2",
|
|
38
|
+
"cors": "^2.8.5",
|
|
39
|
+
"express": "^5.1.0",
|
|
40
|
+
"glob": "^13.0.2",
|
|
41
|
+
"lodash": "^4.17.21",
|
|
42
|
+
"reflect-metadata": "^0.2.2",
|
|
43
|
+
"typeorm": "^0.3.28"
|
|
44
|
+
}
|
|
45
|
+
}
|