badmfck-api-server 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/badmfck-api-server-1.0.1.tgz +0 -0
- package/dist/apiServer/APIService.d.ts +39 -0
- package/dist/apiServer/APIService.js +169 -0
- package/dist/apiServer/BaseEndpoint.d.ts +17 -0
- package/dist/apiServer/BaseEndpoint.js +46 -0
- package/dist/apiServer/BaseService.d.ts +10 -0
- package/dist/apiServer/BaseService.js +14 -0
- package/dist/apiServer/LocalRequest.d.ts +3 -0
- package/dist/apiServer/LocalRequest.js +64 -0
- package/dist/apiServer/structures/DefaultErrors.d.ts +6 -0
- package/dist/apiServer/structures/DefaultErrors.js +7 -0
- package/dist/apiServer/structures/HTTPStatus.d.ts +7 -0
- package/dist/apiServer/structures/HTTPStatus.js +11 -0
- package/dist/apiServer/structures/Interfaces.d.ts +25 -0
- package/dist/apiServer/structures/Interfaces.js +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +8 -0
- package/dist/signal/Signal.d.ts +28 -0
- package/dist/signal/Signal.js +140 -0
- package/package.json +31 -0
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { Response } from 'express';
|
2
|
+
import { BaseService, IBaseService } from './BaseService';
|
3
|
+
import { IBaseEndpoint } from './BaseEndpoint';
|
4
|
+
import { SyncSignal } from '../signal/Signal';
|
5
|
+
import { TransferPacketVO } from './structures/Interfaces';
|
6
|
+
export interface APIServiceNetworkLogItem {
|
7
|
+
id: number;
|
8
|
+
created: number;
|
9
|
+
time: number;
|
10
|
+
request: {
|
11
|
+
[key: string]: any;
|
12
|
+
};
|
13
|
+
response: {
|
14
|
+
[key: string]: any;
|
15
|
+
};
|
16
|
+
error?: string | null;
|
17
|
+
}
|
18
|
+
export interface APIServiceOptions {
|
19
|
+
port: number;
|
20
|
+
baseEndPoint: string;
|
21
|
+
corsHostWhiteList: string[];
|
22
|
+
endpoints: IBaseEndpoint[];
|
23
|
+
jsonLimit: string;
|
24
|
+
onNetworkLog?: ((log: APIServiceNetworkLogItem) => void) | null;
|
25
|
+
onError?: ((...rest: any[]) => void) | null;
|
26
|
+
}
|
27
|
+
export declare function getDefaultOptions(): APIServiceOptions;
|
28
|
+
export declare const REQ_CREATE_NET_LOG: SyncSignal<void, APIServiceNetworkLogItem>;
|
29
|
+
export declare const REQ_HTTP_LOG: SyncSignal<void, APIServiceNetworkLogItem[]>;
|
30
|
+
export declare function Initializer(services: IBaseService[]): Promise<void>;
|
31
|
+
export declare class APIService extends BaseService {
|
32
|
+
private static nextLogID;
|
33
|
+
private version;
|
34
|
+
private options;
|
35
|
+
netLog: APIServiceNetworkLogItem[];
|
36
|
+
constructor(options?: APIServiceOptions | null);
|
37
|
+
init(): Promise<void>;
|
38
|
+
sendResponse(res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null): void;
|
39
|
+
}
|
@@ -0,0 +1,169 @@
|
|
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.APIService = exports.Initializer = exports.REQ_HTTP_LOG = exports.REQ_CREATE_NET_LOG = exports.getDefaultOptions = void 0;
|
7
|
+
const express_1 = __importDefault(require("express"));
|
8
|
+
const BaseService_1 = require("./BaseService");
|
9
|
+
const cors_1 = __importDefault(require("cors"));
|
10
|
+
const BaseEndpoint_1 = require("./BaseEndpoint");
|
11
|
+
const DefaultErrors_1 = __importDefault(require("./structures/DefaultErrors"));
|
12
|
+
const Signal_1 = require("../signal/Signal");
|
13
|
+
function getDefaultOptions() {
|
14
|
+
return {
|
15
|
+
port: 8091,
|
16
|
+
baseEndPoint: '/api/',
|
17
|
+
corsHostWhiteList: [
|
18
|
+
'http://localhost:3000',
|
19
|
+
'http://localhost:8091'
|
20
|
+
],
|
21
|
+
endpoints: [],
|
22
|
+
jsonLimit: "10mb",
|
23
|
+
onNetworkLog: function (log) {
|
24
|
+
console.log(log);
|
25
|
+
},
|
26
|
+
onError: function (err) {
|
27
|
+
console.error.call(this, err);
|
28
|
+
}
|
29
|
+
};
|
30
|
+
}
|
31
|
+
exports.getDefaultOptions = getDefaultOptions;
|
32
|
+
exports.REQ_CREATE_NET_LOG = new Signal_1.SyncSignal();
|
33
|
+
exports.REQ_HTTP_LOG = new Signal_1.SyncSignal();
|
34
|
+
async function Initializer(services) {
|
35
|
+
for (let i of services) {
|
36
|
+
await i.init();
|
37
|
+
}
|
38
|
+
for (let i of services) {
|
39
|
+
i.applicationReady();
|
40
|
+
}
|
41
|
+
}
|
42
|
+
exports.Initializer = Initializer;
|
43
|
+
class APIService extends BaseService_1.BaseService {
|
44
|
+
static nextLogID = 0;
|
45
|
+
version = "1.2.0";
|
46
|
+
options;
|
47
|
+
netLog = [];
|
48
|
+
constructor(options) {
|
49
|
+
super('HTTP Service');
|
50
|
+
this.options = options ?? getDefaultOptions();
|
51
|
+
}
|
52
|
+
async init() {
|
53
|
+
exports.REQ_HTTP_LOG.listener = (ignore, cb) => { cb(this.netLog); };
|
54
|
+
exports.REQ_CREATE_NET_LOG.listener = (ignore, cb) => {
|
55
|
+
const log = {
|
56
|
+
created: +new Date(),
|
57
|
+
time: 0,
|
58
|
+
request: {},
|
59
|
+
response: {},
|
60
|
+
error: null,
|
61
|
+
id: APIService.nextLogID++
|
62
|
+
};
|
63
|
+
this.netLog.push(log);
|
64
|
+
if (this.netLog.length > 1000)
|
65
|
+
this.netLog.shift();
|
66
|
+
cb(log);
|
67
|
+
};
|
68
|
+
const app = (0, express_1.default)();
|
69
|
+
app.use(express_1.default.json({ limit: '10mb' }));
|
70
|
+
app.use(express_1.default.urlencoded({ limit: '10mb', extended: true }));
|
71
|
+
const corsOptions = {
|
72
|
+
origin: (origin, callback) => {
|
73
|
+
const originIsWhitelisted = this.options.corsHostWhiteList.includes(origin);
|
74
|
+
callback(null, originIsWhitelisted);
|
75
|
+
},
|
76
|
+
credentials: true
|
77
|
+
};
|
78
|
+
app.use((0, cors_1.default)(corsOptions));
|
79
|
+
BaseEndpoint_1.BaseEndpoint.setEntryPoint(this.options.baseEndPoint);
|
80
|
+
for (let i of this.options.endpoints) {
|
81
|
+
await i.init();
|
82
|
+
for (let j of i.endpoints) {
|
83
|
+
const ep = BaseEndpoint_1.BaseEndpoint.getEntryPoint() + j;
|
84
|
+
app.all(ep, async (req, res) => {
|
85
|
+
const tme = +new Date();
|
86
|
+
let log = null;
|
87
|
+
if (!i.ignoreHttpLogging) {
|
88
|
+
log = await exports.REQ_CREATE_NET_LOG.request();
|
89
|
+
log.request = {
|
90
|
+
method: req.method,
|
91
|
+
data: req.body,
|
92
|
+
params: req.params
|
93
|
+
};
|
94
|
+
}
|
95
|
+
if (this.options.onNetworkLog && log)
|
96
|
+
this.options.onNetworkLog(log);
|
97
|
+
const execute = async () => {
|
98
|
+
const httpRequest = {
|
99
|
+
raw: req,
|
100
|
+
method: req.method,
|
101
|
+
data: req.body,
|
102
|
+
params: req.params,
|
103
|
+
headers: req.headers,
|
104
|
+
endpoint: ep
|
105
|
+
};
|
106
|
+
const result = await i.execute(httpRequest);
|
107
|
+
this.sendResponse(res, result, tme, ep, log);
|
108
|
+
};
|
109
|
+
execute();
|
110
|
+
});
|
111
|
+
}
|
112
|
+
}
|
113
|
+
app.use((req, res, next) => {
|
114
|
+
const tme = +new Date();
|
115
|
+
this.sendResponse(res, {
|
116
|
+
error: DefaultErrors_1.default.UNKNOWN_REQUEST,
|
117
|
+
data: null,
|
118
|
+
httpStatus: 404
|
119
|
+
}, tme, req.path);
|
120
|
+
});
|
121
|
+
app.listen(this.options.port, () => {
|
122
|
+
console.log('API Service started at: ' + this.options.port + ", with base endpoint:" + this.options.baseEndPoint + ", ver.: " + this.version);
|
123
|
+
});
|
124
|
+
}
|
125
|
+
sendResponse(res, data, requestTime, endpoint, log) {
|
126
|
+
data.responseTime = (+new Date()) - requestTime;
|
127
|
+
data.version = this.version;
|
128
|
+
data.endpoint = endpoint ?? "no_endpoint";
|
129
|
+
if (log)
|
130
|
+
log.time = data.responseTime;
|
131
|
+
if (res.destroyed || res.closed) {
|
132
|
+
if (log)
|
133
|
+
log.error = "Connection already closed, can't send response";
|
134
|
+
if (this.options.onError)
|
135
|
+
this.options.onError("Connection already closed, can't send response", data);
|
136
|
+
}
|
137
|
+
else {
|
138
|
+
try {
|
139
|
+
if (data.redirect) {
|
140
|
+
res.redirect(data.redirect);
|
141
|
+
if (log)
|
142
|
+
log.response = { redirect: data.redirect };
|
143
|
+
}
|
144
|
+
else {
|
145
|
+
res.statusCode = data.httpStatus ?? 200;
|
146
|
+
if (data.rawResponse) {
|
147
|
+
res.send(data.data);
|
148
|
+
if (log)
|
149
|
+
log.response = data.data;
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
res.send(data);
|
153
|
+
if (log)
|
154
|
+
log.response = data;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
catch (e) {
|
159
|
+
if (this.options.onError)
|
160
|
+
this.options.onError("Can't send response", e);
|
161
|
+
if (log)
|
162
|
+
log.error = "Can't send response";
|
163
|
+
}
|
164
|
+
}
|
165
|
+
if (this.options.onNetworkLog && log)
|
166
|
+
this.options.onNetworkLog(log);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
exports.APIService = APIService;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { HTTPRequestVO, TransferPacketVO } from "./structures/Interfaces";
|
2
|
+
export interface IBaseEndpoint {
|
3
|
+
endpoints: string[];
|
4
|
+
execute: (req: HTTPRequestVO) => Promise<TransferPacketVO<any>>;
|
5
|
+
init: () => Promise<void>;
|
6
|
+
ignoreHttpLogging: boolean;
|
7
|
+
}
|
8
|
+
export declare class BaseEndpoint implements IBaseEndpoint {
|
9
|
+
ignoreHttpLogging: boolean;
|
10
|
+
private static entrypoint;
|
11
|
+
static setEntryPoint: (ep: string) => void;
|
12
|
+
static getEntryPoint: () => string;
|
13
|
+
endpoints: string[];
|
14
|
+
constructor(ep: string | string[]);
|
15
|
+
init(): Promise<void>;
|
16
|
+
execute(req: HTTPRequestVO): Promise<TransferPacketVO<any>>;
|
17
|
+
}
|
@@ -0,0 +1,46 @@
|
|
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.BaseEndpoint = void 0;
|
7
|
+
const DefaultErrors_1 = __importDefault(require("./structures/DefaultErrors"));
|
8
|
+
class BaseEndpoint {
|
9
|
+
ignoreHttpLogging = false;
|
10
|
+
static entrypoint = "/";
|
11
|
+
static setEntryPoint = (ep) => {
|
12
|
+
this.entrypoint = ep;
|
13
|
+
if (!this.entrypoint.endsWith("/")) {
|
14
|
+
this.entrypoint += "/";
|
15
|
+
}
|
16
|
+
if (!ep.startsWith("/"))
|
17
|
+
this.entrypoint = "/" + ep;
|
18
|
+
};
|
19
|
+
static getEntryPoint = () => {
|
20
|
+
return this.entrypoint;
|
21
|
+
};
|
22
|
+
endpoints;
|
23
|
+
constructor(ep) {
|
24
|
+
if (typeof ep === "string")
|
25
|
+
ep = [ep];
|
26
|
+
let eps = [];
|
27
|
+
for (let i of ep) {
|
28
|
+
if (i.startsWith("/"))
|
29
|
+
i = i.substring(1);
|
30
|
+
eps.push(i);
|
31
|
+
}
|
32
|
+
this.endpoints = eps;
|
33
|
+
}
|
34
|
+
async init() {
|
35
|
+
for (let i of this.endpoints)
|
36
|
+
console.log("endpoint: " + BaseEndpoint.entrypoint + i + " initalized");
|
37
|
+
}
|
38
|
+
;
|
39
|
+
async execute(req) {
|
40
|
+
return {
|
41
|
+
error: DefaultErrors_1.default.NOT_IMPLEMENTED,
|
42
|
+
data: null
|
43
|
+
};
|
44
|
+
}
|
45
|
+
}
|
46
|
+
exports.BaseEndpoint = BaseEndpoint;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export interface IBaseService {
|
2
|
+
init: () => Promise<void>;
|
3
|
+
applicationReady: () => void;
|
4
|
+
}
|
5
|
+
export declare class BaseService implements IBaseService {
|
6
|
+
protected name: string;
|
7
|
+
constructor(name: string);
|
8
|
+
init(): Promise<void>;
|
9
|
+
applicationReady(): void;
|
10
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.BaseService = void 0;
|
4
|
+
class BaseService {
|
5
|
+
name;
|
6
|
+
constructor(name) {
|
7
|
+
this.name = name;
|
8
|
+
}
|
9
|
+
async init() {
|
10
|
+
console.log("Service: " + this.name + " initialized");
|
11
|
+
}
|
12
|
+
applicationReady() { }
|
13
|
+
}
|
14
|
+
exports.BaseService = BaseService;
|
@@ -0,0 +1,64 @@
|
|
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.LocalRequest = void 0;
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
8
|
+
axios_1.default.interceptors.request.use((x) => {
|
9
|
+
console.log(`AXIOS REQ:\n\turl:${x.url}\n\tmethod: ${x.method}\n\tdata: ${(() => {
|
10
|
+
if (typeof x.data === "string")
|
11
|
+
return x.data;
|
12
|
+
return JSON.stringify(x.data, null, "\t\t");
|
13
|
+
})()}\n\theaders:\n${(() => {
|
14
|
+
let h = "";
|
15
|
+
for (let i in x.headers) {
|
16
|
+
if (h !== "")
|
17
|
+
h += "\n";
|
18
|
+
h += "\t\t" + i + " = " + x.headers[i];
|
19
|
+
}
|
20
|
+
return h;
|
21
|
+
})()}`);
|
22
|
+
return x;
|
23
|
+
});
|
24
|
+
axios_1.default.interceptors.response.use((x) => {
|
25
|
+
console.log(`AXIOS RESP:\n\tdata: ${(() => {
|
26
|
+
if (typeof x.data === "string")
|
27
|
+
return x.data;
|
28
|
+
return JSON.stringify(x.data, null, "\t\t");
|
29
|
+
})()}\n\theaders:\n${(() => {
|
30
|
+
let h = "";
|
31
|
+
for (let i in x.headers) {
|
32
|
+
if (h !== "")
|
33
|
+
h += "\n";
|
34
|
+
h += "\t\t" + i + " = " + x.headers[i];
|
35
|
+
}
|
36
|
+
return h;
|
37
|
+
})()}`);
|
38
|
+
return x;
|
39
|
+
});
|
40
|
+
const LocalRequest = async (ep, data, method, headers) => {
|
41
|
+
let m = "get";
|
42
|
+
if (method)
|
43
|
+
m = method.toLowerCase();
|
44
|
+
if (data && !method)
|
45
|
+
m = "post";
|
46
|
+
if (ep.startsWith("/"))
|
47
|
+
ep = ep.substring(1);
|
48
|
+
let url = "http://localhost:8091/" + ep;
|
49
|
+
if (ep.toLowerCase().startsWith("http"))
|
50
|
+
url = ep;
|
51
|
+
let resp = null;
|
52
|
+
console.log("open url: ", url);
|
53
|
+
try {
|
54
|
+
if (m === "get")
|
55
|
+
resp = await axios_1.default.get(url, { headers: headers });
|
56
|
+
if (m === "post")
|
57
|
+
resp = await axios_1.default.post(url, data, { headers: headers });
|
58
|
+
}
|
59
|
+
catch (e) {
|
60
|
+
console.log("ERROR! cant open url", e);
|
61
|
+
}
|
62
|
+
console.log(resp);
|
63
|
+
};
|
64
|
+
exports.LocalRequest = LocalRequest;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class DefaultErrors {
|
4
|
+
static NOT_IMPLEMENTED = { code: 1, message: "Not implemented" };
|
5
|
+
static UNKNOWN_REQUEST = { code: 2, message: "Unknown request" };
|
6
|
+
}
|
7
|
+
exports.default = DefaultErrors;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.HTTP_STATUS = void 0;
|
4
|
+
var HTTP_STATUS;
|
5
|
+
(function (HTTP_STATUS) {
|
6
|
+
HTTP_STATUS[HTTP_STATUS["OK"] = 200] = "OK";
|
7
|
+
HTTP_STATUS[HTTP_STATUS["NOT_FOUND"] = 404] = "NOT_FOUND";
|
8
|
+
HTTP_STATUS[HTTP_STATUS["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
9
|
+
HTTP_STATUS[HTTP_STATUS["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
10
|
+
HTTP_STATUS[HTTP_STATUS["SERVER_ERROR"] = 500] = "SERVER_ERROR";
|
11
|
+
})(HTTP_STATUS = exports.HTTP_STATUS || (exports.HTTP_STATUS = {}));
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export interface TransferPacketVO<T> {
|
2
|
+
data?: T | null;
|
3
|
+
error?: ErrorVO | null;
|
4
|
+
responseTime?: number;
|
5
|
+
version?: string;
|
6
|
+
endpoint?: string;
|
7
|
+
httpStatus?: number;
|
8
|
+
redirect?: string;
|
9
|
+
rawResponse?: boolean;
|
10
|
+
}
|
11
|
+
export interface HTTPRequestVO {
|
12
|
+
raw: any;
|
13
|
+
method: string;
|
14
|
+
data: any;
|
15
|
+
params: {
|
16
|
+
[key: string]: string;
|
17
|
+
};
|
18
|
+
headers: any;
|
19
|
+
endpoint: string;
|
20
|
+
}
|
21
|
+
export interface ErrorVO {
|
22
|
+
code: number;
|
23
|
+
message: string;
|
24
|
+
details?: string;
|
25
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.LocalRequest = exports.Initializer = exports.APIService = void 0;
|
4
|
+
const APIService_1 = require("./apiServer/APIService");
|
5
|
+
Object.defineProperty(exports, "APIService", { enumerable: true, get: function () { return APIService_1.APIService; } });
|
6
|
+
Object.defineProperty(exports, "Initializer", { enumerable: true, get: function () { return APIService_1.Initializer; } });
|
7
|
+
const LocalRequest_1 = require("./apiServer/LocalRequest");
|
8
|
+
Object.defineProperty(exports, "LocalRequest", { enumerable: true, get: function () { return LocalRequest_1.LocalRequest; } });
|
@@ -0,0 +1,28 @@
|
|
1
|
+
declare class Signal<T> {
|
2
|
+
static nextID: number;
|
3
|
+
private busy;
|
4
|
+
private tempAdd;
|
5
|
+
private tempRem;
|
6
|
+
private tempInvoke;
|
7
|
+
private callbacks;
|
8
|
+
private tempClear;
|
9
|
+
constructor(name?: string);
|
10
|
+
add(callback: (data: T) => void, id?: string): string;
|
11
|
+
clear(): void;
|
12
|
+
remove(callback?: (data: T) => void, id?: string): string | undefined;
|
13
|
+
invoke(data: T): void;
|
14
|
+
}
|
15
|
+
export declare class SignalHandler {
|
16
|
+
static nextID: number;
|
17
|
+
private id;
|
18
|
+
private signals;
|
19
|
+
constructor();
|
20
|
+
add<T>(signal: Signal<T>, cb: (data: T) => void): void;
|
21
|
+
clear(): void;
|
22
|
+
}
|
23
|
+
export declare class SyncSignal<T, K> {
|
24
|
+
private worker?;
|
25
|
+
request(data: T): Promise<K>;
|
26
|
+
set listener(_listener: (request: T, response: (data: K) => void) => void);
|
27
|
+
}
|
28
|
+
export default Signal;
|
@@ -0,0 +1,140 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.SyncSignal = exports.SignalHandler = void 0;
|
4
|
+
class Signal {
|
5
|
+
static nextID = 0;
|
6
|
+
busy = false;
|
7
|
+
tempAdd = [];
|
8
|
+
tempRem = [];
|
9
|
+
tempInvoke = [];
|
10
|
+
callbacks = [];
|
11
|
+
tempClear = false;
|
12
|
+
constructor(name) { }
|
13
|
+
add(callback, id) {
|
14
|
+
if (!id)
|
15
|
+
id = "" + (Signal.nextID++);
|
16
|
+
if (this.busy) {
|
17
|
+
for (let i of this.tempAdd) {
|
18
|
+
if (i.cb === callback)
|
19
|
+
return i.id;
|
20
|
+
}
|
21
|
+
this.tempAdd.push({ cb: callback, id: id });
|
22
|
+
return id;
|
23
|
+
}
|
24
|
+
for (let i of this.callbacks) {
|
25
|
+
if (i.cb === callback)
|
26
|
+
return i.id;
|
27
|
+
}
|
28
|
+
this.callbacks.push({ cb: callback, id: id });
|
29
|
+
return id;
|
30
|
+
}
|
31
|
+
clear() {
|
32
|
+
if (this.busy) {
|
33
|
+
this.tempClear = true;
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
this.callbacks = [];
|
37
|
+
}
|
38
|
+
remove(callback, id) {
|
39
|
+
if (!callback && !id)
|
40
|
+
return;
|
41
|
+
if (this.busy) {
|
42
|
+
for (let i of this.tempRem) {
|
43
|
+
if (callback) {
|
44
|
+
if (i.cb === callback)
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
if (id) {
|
48
|
+
if (i.id === id)
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
this.tempRem.push({ cb: callback, id: id });
|
53
|
+
return id;
|
54
|
+
}
|
55
|
+
for (let i = 0; i < this.callbacks.length; i++) {
|
56
|
+
const itm = this.callbacks[i];
|
57
|
+
let remove = false;
|
58
|
+
if (callback)
|
59
|
+
remove = itm.cb === callback;
|
60
|
+
if (id)
|
61
|
+
remove = remove || itm.id === id;
|
62
|
+
if (remove) {
|
63
|
+
this.callbacks.splice(i, 1);
|
64
|
+
i--;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
invoke(data) {
|
69
|
+
if (this.busy) {
|
70
|
+
this.tempInvoke.push({ data: data });
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
this.busy = true;
|
74
|
+
for (let i of this.callbacks) {
|
75
|
+
if (i && i.cb && typeof i.cb === "function") {
|
76
|
+
i.cb(data);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
this.busy = false;
|
80
|
+
for (let i of this.tempAdd) {
|
81
|
+
this.add(i.cb, i.id);
|
82
|
+
}
|
83
|
+
this.tempAdd = [];
|
84
|
+
for (let i of this.tempRem) {
|
85
|
+
this.remove(i.cb, i.id);
|
86
|
+
}
|
87
|
+
this.tempRem = [];
|
88
|
+
for (let i of this.tempInvoke) {
|
89
|
+
this.invoke(i.data);
|
90
|
+
}
|
91
|
+
if (this.tempClear)
|
92
|
+
this.clear();
|
93
|
+
}
|
94
|
+
}
|
95
|
+
class SignalHandler {
|
96
|
+
static nextID = 0;
|
97
|
+
id;
|
98
|
+
signals = [];
|
99
|
+
constructor() {
|
100
|
+
this.id = SignalHandler.nextID++;
|
101
|
+
}
|
102
|
+
add(signal, cb) {
|
103
|
+
let added = false;
|
104
|
+
for (let i of this.signals) {
|
105
|
+
if (i === signal) {
|
106
|
+
added = true;
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
if (!added)
|
111
|
+
this.signals.push(signal);
|
112
|
+
signal.add(cb, "signaller_" + this.id);
|
113
|
+
}
|
114
|
+
clear() {
|
115
|
+
for (let i of this.signals)
|
116
|
+
i.remove(undefined, "signaller_" + this.id);
|
117
|
+
this.signals = [];
|
118
|
+
}
|
119
|
+
}
|
120
|
+
exports.SignalHandler = SignalHandler;
|
121
|
+
class SyncSignal {
|
122
|
+
worker;
|
123
|
+
request(data) {
|
124
|
+
const executor = (resolve, reject) => {
|
125
|
+
if (!this.worker) {
|
126
|
+
console.error("No worker registered in SyncSignal");
|
127
|
+
reject("No worker registered in SyncSignal");
|
128
|
+
return;
|
129
|
+
}
|
130
|
+
this.worker(data, resolve);
|
131
|
+
};
|
132
|
+
const promise = new Promise(executor);
|
133
|
+
return promise;
|
134
|
+
}
|
135
|
+
set listener(_listener) {
|
136
|
+
this.worker = _listener;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
exports.SyncSignal = SyncSignal;
|
140
|
+
exports.default = Signal;
|
package/package.json
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
{
|
2
|
+
"name": "badmfck-api-server",
|
3
|
+
"version": "1.0.1",
|
4
|
+
"description": "Simple API http server based on express",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"types": "dist/index.d.ts",
|
7
|
+
"scripts": {
|
8
|
+
"prepublish": "tsc",
|
9
|
+
"build":"tsc",
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
11
|
+
},
|
12
|
+
"keywords": [
|
13
|
+
"api",
|
14
|
+
"rest",
|
15
|
+
"http",
|
16
|
+
"server",
|
17
|
+
"express"
|
18
|
+
],
|
19
|
+
"dependencies": {
|
20
|
+
"axios": "^1.4.0",
|
21
|
+
"badmfck-signal": "^1.0.1",
|
22
|
+
"cors": "^2.8.5",
|
23
|
+
"express": "^4.18.2"
|
24
|
+
},
|
25
|
+
"devDependencies": {
|
26
|
+
"@types/cors": "^2.8.13",
|
27
|
+
"@types/express": "^4.17.17"
|
28
|
+
},
|
29
|
+
"author": "Igor Bloom",
|
30
|
+
"license": "MIT"
|
31
|
+
}
|