@napp/dti-server 4.4.4 → 4.5.2
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/action.d.ts +5 -3
- package/action.js +38 -1
- package/bundler.js +22 -33
- package/common.d.ts +3 -0
- package/esm/action.d.ts +15 -0
- package/esm/action.js +52 -0
- package/esm/bundler.d.ts +14 -0
- package/esm/bundler.js +57 -0
- package/esm/common.d.ts +25 -0
- package/esm/common.js +1 -0
- package/esm/index.d.ts +4 -0
- package/esm/index.js +4 -0
- package/esm/route.d.ts +15 -0
- package/esm/route.js +109 -0
- package/esm/server.d.ts +22 -0
- package/esm/server.js +51 -0
- package/package.json +10 -2
- package/route.js +8 -7
- package/server.d.ts +5 -0
- package/server.js +8 -2
package/action.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { DtiAction } from "@napp/dti-core";
|
|
2
|
-
import { IContext } from "./common";
|
|
1
|
+
import type { DtiAction } from "@napp/dti-core";
|
|
2
|
+
import type { IContext } from "./common";
|
|
3
|
+
import type { DtiServer } from "./server";
|
|
4
|
+
import type { Request } from "express";
|
|
3
5
|
export interface ODtiServerAction<RESULT, PARAM> {
|
|
4
6
|
action: (param: PARAM, ctx: IContext) => Promise<RESULT>;
|
|
5
7
|
}
|
|
@@ -8,6 +10,6 @@ export declare class DtiServerAction<RESULT, PARAM> {
|
|
|
8
10
|
private opt;
|
|
9
11
|
private constructor();
|
|
10
12
|
action(param: PARAM, ctx: IContext): Promise<RESULT>;
|
|
11
|
-
validation(param: PARAM): void
|
|
13
|
+
validation(server: DtiServer, param: PARAM, req: Request, isBundler?: boolean): Promise<void>;
|
|
12
14
|
static factory<RESULT, PARAM>(meta: DtiAction<RESULT, PARAM>, opt: ODtiServerAction<RESULT, PARAM>): DtiServerAction<RESULT, PARAM>;
|
|
13
15
|
}
|
package/action.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DtiServerAction = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
function createHmacString(secret, data) {
|
|
6
|
+
const expected = (0, node_crypto_1.createHmac)("sha256", secret)
|
|
7
|
+
.update(data, "utf8")
|
|
8
|
+
.digest("base64");
|
|
9
|
+
return expected;
|
|
10
|
+
}
|
|
4
11
|
class DtiServerAction {
|
|
12
|
+
meta;
|
|
13
|
+
opt;
|
|
5
14
|
constructor(meta, opt) {
|
|
6
15
|
this.meta = meta;
|
|
7
16
|
this.opt = opt;
|
|
@@ -9,8 +18,36 @@ class DtiServerAction {
|
|
|
9
18
|
action(param, ctx) {
|
|
10
19
|
return this.opt.action(param, ctx);
|
|
11
20
|
}
|
|
12
|
-
validation(param) {
|
|
21
|
+
async validation(server, param, req, isBundler = false) {
|
|
13
22
|
this.meta.validate(param);
|
|
23
|
+
if (server.signatureSecret && isBundler === false) {
|
|
24
|
+
const data = this.meta.sign(param);
|
|
25
|
+
if (data) {
|
|
26
|
+
const timestamp = req.get('X-DTI-Timestamp') ?? '';
|
|
27
|
+
const nonce = req.get('X-DTI-Nonce') ?? '';
|
|
28
|
+
const signature = req.get('X-DTI-Signature') ?? '';
|
|
29
|
+
if (!(timestamp && nonce && signature)) {
|
|
30
|
+
throw new Error('requared signature');
|
|
31
|
+
}
|
|
32
|
+
const secret = await server.signatureSecret();
|
|
33
|
+
const expected = createHmacString(secret, `${timestamp}.${nonce}.${data}`);
|
|
34
|
+
// console.log('--------method', req.method, this.meta.getFullname() )
|
|
35
|
+
// console.log('secret', secret)
|
|
36
|
+
// console.log('timestamp', timestamp)
|
|
37
|
+
// console.log('nonce', nonce)
|
|
38
|
+
// console.log('signature', signature)
|
|
39
|
+
// console.log('expected', expected)
|
|
40
|
+
const a = Buffer.from(expected, "base64");
|
|
41
|
+
const b = Buffer.from(signature, 'base64');
|
|
42
|
+
if (a.length !== b.length) {
|
|
43
|
+
throw new Error("invalid signature");
|
|
44
|
+
}
|
|
45
|
+
const valid = (0, node_crypto_1.timingSafeEqual)(new Uint8Array(a), new Uint8Array(b));
|
|
46
|
+
if (valid === false) {
|
|
47
|
+
throw new Error("invalid signature");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
14
51
|
}
|
|
15
52
|
static factory(meta, opt) {
|
|
16
53
|
return new DtiServerAction(meta, opt);
|
package/bundler.js
CHANGED
|
@@ -1,58 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.BundlerServer = void 0;
|
|
13
4
|
const dti_core_1 = require("@napp/dti-core");
|
|
14
5
|
class BundlerServer {
|
|
6
|
+
server;
|
|
7
|
+
base62 = new dti_core_1.Base62();
|
|
15
8
|
constructor(server) {
|
|
16
9
|
this.server = server;
|
|
17
|
-
this.base62 = new dti_core_1.Base62();
|
|
18
10
|
}
|
|
19
|
-
action(meta, ctx) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
actions.push(() => __awaiter(this, void 0, void 0, function* () { return yield (action === null || action === void 0 ? void 0 : action.action(it.param, ctx)); }));
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
throw new Error('not defined action. name=' + it.name);
|
|
31
|
-
}
|
|
11
|
+
async action(meta, ctx) {
|
|
12
|
+
let actions = [];
|
|
13
|
+
for (let it of meta) {
|
|
14
|
+
let action = this.server.getActionByName(it.name);
|
|
15
|
+
if (action) {
|
|
16
|
+
await action.validation(this.server, it.param, ctx.req, true);
|
|
17
|
+
// console.log('call', it.name, it.param, await action?.action(it.param, ctx))
|
|
18
|
+
actions.push(async () => await action?.action(it.param, ctx));
|
|
32
19
|
}
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
else {
|
|
21
|
+
throw new Error('not defined action. name=' + it.name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return await Promise.all(actions.map(it => it()));
|
|
35
25
|
}
|
|
36
26
|
setup(expressRoute, setuper) {
|
|
37
27
|
if (setuper.factoryBodyparseJson) {
|
|
38
|
-
expressRoute.post('/__bundler_post__', setuper.factoryBodyparseJson(), (req, res, next) =>
|
|
28
|
+
expressRoute.post('/__bundler_post__', setuper.factoryBodyparseJson(), async (req, res, next) => {
|
|
39
29
|
try {
|
|
40
30
|
let meta = req.body || [];
|
|
41
|
-
let result =
|
|
31
|
+
let result = await this.action(meta, { req, res });
|
|
42
32
|
res.json(result);
|
|
43
33
|
}
|
|
44
34
|
catch (error) {
|
|
45
35
|
next(error);
|
|
46
36
|
}
|
|
47
|
-
})
|
|
48
|
-
expressRoute.get('/__bundler_get__', (req, res, next) =>
|
|
49
|
-
var _a;
|
|
37
|
+
});
|
|
38
|
+
expressRoute.get('/__bundler_get__', async (req, res, next) => {
|
|
50
39
|
try {
|
|
51
|
-
let p =
|
|
40
|
+
let p = req.query?.p;
|
|
52
41
|
if (p) {
|
|
53
42
|
let json = this.base62.decode(p);
|
|
54
43
|
let meta = JSON.parse(json);
|
|
55
|
-
let result =
|
|
44
|
+
let result = await this.action(meta, { req, res });
|
|
56
45
|
res.json(result);
|
|
57
46
|
}
|
|
58
47
|
else {
|
|
@@ -62,7 +51,7 @@ class BundlerServer {
|
|
|
62
51
|
catch (error) {
|
|
63
52
|
next(error);
|
|
64
53
|
}
|
|
65
|
-
})
|
|
54
|
+
});
|
|
66
55
|
}
|
|
67
56
|
else {
|
|
68
57
|
throw new Error('not defined server.factoryBodyparseJson');
|
package/common.d.ts
CHANGED
package/esm/action.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DtiAction } from "@napp/dti-core";
|
|
2
|
+
import type { IContext } from "./common";
|
|
3
|
+
import type { DtiServer } from "./server";
|
|
4
|
+
import type { Request } from "express";
|
|
5
|
+
export interface ODtiServerAction<RESULT, PARAM> {
|
|
6
|
+
action: (param: PARAM, ctx: IContext) => Promise<RESULT>;
|
|
7
|
+
}
|
|
8
|
+
export declare class DtiServerAction<RESULT, PARAM> {
|
|
9
|
+
meta: DtiAction<RESULT, PARAM>;
|
|
10
|
+
private opt;
|
|
11
|
+
private constructor();
|
|
12
|
+
action(param: PARAM, ctx: IContext): Promise<RESULT>;
|
|
13
|
+
validation(server: DtiServer, param: PARAM, req: Request, isBundler?: boolean): Promise<void>;
|
|
14
|
+
static factory<RESULT, PARAM>(meta: DtiAction<RESULT, PARAM>, opt: ODtiServerAction<RESULT, PARAM>): DtiServerAction<RESULT, PARAM>;
|
|
15
|
+
}
|
package/esm/action.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
function createHmacString(secret, data) {
|
|
3
|
+
const expected = createHmac("sha256", secret)
|
|
4
|
+
.update(data, "utf8")
|
|
5
|
+
.digest("base64");
|
|
6
|
+
return expected;
|
|
7
|
+
}
|
|
8
|
+
export class DtiServerAction {
|
|
9
|
+
meta;
|
|
10
|
+
opt;
|
|
11
|
+
constructor(meta, opt) {
|
|
12
|
+
this.meta = meta;
|
|
13
|
+
this.opt = opt;
|
|
14
|
+
}
|
|
15
|
+
action(param, ctx) {
|
|
16
|
+
return this.opt.action(param, ctx);
|
|
17
|
+
}
|
|
18
|
+
async validation(server, param, req, isBundler = false) {
|
|
19
|
+
this.meta.validate(param);
|
|
20
|
+
if (server.signatureSecret && isBundler === false) {
|
|
21
|
+
const data = this.meta.sign(param);
|
|
22
|
+
if (data) {
|
|
23
|
+
const timestamp = req.get('X-DTI-Timestamp') ?? '';
|
|
24
|
+
const nonce = req.get('X-DTI-Nonce') ?? '';
|
|
25
|
+
const signature = req.get('X-DTI-Signature') ?? '';
|
|
26
|
+
if (!(timestamp && nonce && signature)) {
|
|
27
|
+
throw new Error('requared signature');
|
|
28
|
+
}
|
|
29
|
+
const secret = await server.signatureSecret();
|
|
30
|
+
const expected = createHmacString(secret, `${timestamp}.${nonce}.${data}`);
|
|
31
|
+
// console.log('--------method', req.method, this.meta.getFullname() )
|
|
32
|
+
// console.log('secret', secret)
|
|
33
|
+
// console.log('timestamp', timestamp)
|
|
34
|
+
// console.log('nonce', nonce)
|
|
35
|
+
// console.log('signature', signature)
|
|
36
|
+
// console.log('expected', expected)
|
|
37
|
+
const a = Buffer.from(expected, "base64");
|
|
38
|
+
const b = Buffer.from(signature, 'base64');
|
|
39
|
+
if (a.length !== b.length) {
|
|
40
|
+
throw new Error("invalid signature");
|
|
41
|
+
}
|
|
42
|
+
const valid = timingSafeEqual(new Uint8Array(a), new Uint8Array(b));
|
|
43
|
+
if (valid === false) {
|
|
44
|
+
throw new Error("invalid signature");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
static factory(meta, opt) {
|
|
50
|
+
return new DtiServerAction(meta, opt);
|
|
51
|
+
}
|
|
52
|
+
}
|
package/esm/bundler.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IContext, OSetupParam } from "./common";
|
|
2
|
+
import { DtiServer } from "./server";
|
|
3
|
+
interface IMeteParam {
|
|
4
|
+
name: string;
|
|
5
|
+
param: any;
|
|
6
|
+
}
|
|
7
|
+
export declare class BundlerServer {
|
|
8
|
+
private server;
|
|
9
|
+
private base62;
|
|
10
|
+
constructor(server: DtiServer);
|
|
11
|
+
action(meta: Array<IMeteParam>, ctx: IContext): Promise<any[]>;
|
|
12
|
+
setup(expressRoute: any, setuper: OSetupParam): void;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
package/esm/bundler.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Base62 } from "@napp/dti-core";
|
|
2
|
+
export class BundlerServer {
|
|
3
|
+
server;
|
|
4
|
+
base62 = new Base62();
|
|
5
|
+
constructor(server) {
|
|
6
|
+
this.server = server;
|
|
7
|
+
}
|
|
8
|
+
async action(meta, ctx) {
|
|
9
|
+
let actions = [];
|
|
10
|
+
for (let it of meta) {
|
|
11
|
+
let action = this.server.getActionByName(it.name);
|
|
12
|
+
if (action) {
|
|
13
|
+
await action.validation(this.server, it.param, ctx.req, true);
|
|
14
|
+
// console.log('call', it.name, it.param, await action?.action(it.param, ctx))
|
|
15
|
+
actions.push(async () => await action?.action(it.param, ctx));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
throw new Error('not defined action. name=' + it.name);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return await Promise.all(actions.map(it => it()));
|
|
22
|
+
}
|
|
23
|
+
setup(expressRoute, setuper) {
|
|
24
|
+
if (setuper.factoryBodyparseJson) {
|
|
25
|
+
expressRoute.post('/__bundler_post__', setuper.factoryBodyparseJson(), async (req, res, next) => {
|
|
26
|
+
try {
|
|
27
|
+
let meta = req.body || [];
|
|
28
|
+
let result = await this.action(meta, { req, res });
|
|
29
|
+
res.json(result);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
next(error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
expressRoute.get('/__bundler_get__', async (req, res, next) => {
|
|
36
|
+
try {
|
|
37
|
+
let p = req.query?.p;
|
|
38
|
+
if (p) {
|
|
39
|
+
let json = this.base62.decode(p);
|
|
40
|
+
let meta = JSON.parse(json);
|
|
41
|
+
let result = await this.action(meta, { req, res });
|
|
42
|
+
res.json(result);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
res.json([]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
next(error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error('not defined server.factoryBodyparseJson');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
package/esm/common.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DtiRoute } from "@napp/dti-core";
|
|
2
|
+
export interface IContext {
|
|
3
|
+
req: any;
|
|
4
|
+
res: any;
|
|
5
|
+
}
|
|
6
|
+
export interface IMiddleware {
|
|
7
|
+
(req: any, res: any, next: any): void;
|
|
8
|
+
}
|
|
9
|
+
export interface IErrorHandle {
|
|
10
|
+
(req: any, res: any, next: any): void;
|
|
11
|
+
}
|
|
12
|
+
export interface IExpressRoute {
|
|
13
|
+
get(path: string, handlers: IMiddleware[]): void;
|
|
14
|
+
post(path: string, handlers: IMiddleware[]): void;
|
|
15
|
+
use(path: string, route: IExpressRoute): void;
|
|
16
|
+
}
|
|
17
|
+
export interface OSetupParam {
|
|
18
|
+
factoryExpressRouter(dtiRouter: DtiRoute): any;
|
|
19
|
+
factoryBodyparseJson?: () => IMiddleware;
|
|
20
|
+
factoryBodyparseUrlencode?: () => IMiddleware;
|
|
21
|
+
errorHandle?: IErrorHandle;
|
|
22
|
+
signatureSecret?: {
|
|
23
|
+
(): Promise<string>;
|
|
24
|
+
};
|
|
25
|
+
}
|
package/esm/common.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/esm/index.d.ts
ADDED
package/esm/index.js
ADDED
package/esm/route.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DtiRoute } from "@napp/dti-core";
|
|
2
|
+
import { OSetupParam } from "./common";
|
|
3
|
+
import { DtiServer } from "./server";
|
|
4
|
+
export declare class DtiServerRoute {
|
|
5
|
+
private meta;
|
|
6
|
+
private server;
|
|
7
|
+
private base62;
|
|
8
|
+
constructor(meta: DtiRoute, server: DtiServer);
|
|
9
|
+
private param;
|
|
10
|
+
private callAction;
|
|
11
|
+
private setupAction;
|
|
12
|
+
private setupActions;
|
|
13
|
+
private setupRaws;
|
|
14
|
+
setup(setuper: OSetupParam): any;
|
|
15
|
+
}
|
package/esm/route.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { DtiMode, Base62, DtiRawResponse } from "@napp/dti-core";
|
|
2
|
+
export class DtiServerRoute {
|
|
3
|
+
meta;
|
|
4
|
+
server;
|
|
5
|
+
base62 = new Base62();
|
|
6
|
+
constructor(meta, server) {
|
|
7
|
+
this.meta = meta;
|
|
8
|
+
this.server = server;
|
|
9
|
+
}
|
|
10
|
+
param(action, req) {
|
|
11
|
+
let mode = action.meta.getMode();
|
|
12
|
+
if (mode === DtiMode.QString) {
|
|
13
|
+
return req.query;
|
|
14
|
+
}
|
|
15
|
+
else if (mode === DtiMode.QJson) {
|
|
16
|
+
try {
|
|
17
|
+
let p = req.query?.p;
|
|
18
|
+
if (p) {
|
|
19
|
+
let json = this.base62.decode(p);
|
|
20
|
+
return JSON.parse(json);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
else if (mode === DtiMode.BJson || mode === DtiMode.BFrom) {
|
|
28
|
+
return req.body;
|
|
29
|
+
}
|
|
30
|
+
throw new Error('not supported mode');
|
|
31
|
+
}
|
|
32
|
+
async callAction(sa, req, res, next) {
|
|
33
|
+
try {
|
|
34
|
+
let param = this.param(sa, req);
|
|
35
|
+
await sa.validation(this.server, param, req);
|
|
36
|
+
return sa.action(param, { req, res })
|
|
37
|
+
.then(rsu => {
|
|
38
|
+
if (DtiRawResponse.is(rsu) === false) {
|
|
39
|
+
return res.json(rsu);
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.catch(err => next(err));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return next(error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
setupAction(expressRoute, action, setuper) {
|
|
49
|
+
let mode = action.meta.getMode();
|
|
50
|
+
let path = action.meta.getPath();
|
|
51
|
+
let endpoint = async (req, res, next) => {
|
|
52
|
+
await this.callAction(action, req, res, next);
|
|
53
|
+
};
|
|
54
|
+
if (mode === DtiMode.QString || mode === DtiMode.QJson) {
|
|
55
|
+
expressRoute.get(path, endpoint);
|
|
56
|
+
}
|
|
57
|
+
else if (mode === DtiMode.BJson) {
|
|
58
|
+
if (setuper.factoryBodyparseJson) {
|
|
59
|
+
expressRoute.post(path, [setuper.factoryBodyparseJson(), endpoint]);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
throw new Error('not define server.factoryBodyparseJson');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (mode === DtiMode.BFrom) {
|
|
66
|
+
if (setuper.factoryBodyparseUrlencode) {
|
|
67
|
+
expressRoute.post(path, [setuper.factoryBodyparseUrlencode(), endpoint]);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
throw new Error('not define server.factoryBodyparseUrlencode');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
throw new Error("not support methid. logic error");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
setupActions(expressRoute, setuper) {
|
|
78
|
+
let actions = this.meta.getActions();
|
|
79
|
+
for (let a of actions) {
|
|
80
|
+
let name = a.getFullname();
|
|
81
|
+
let action = this.server.getActionByName(name);
|
|
82
|
+
if (action) {
|
|
83
|
+
this.setupAction(expressRoute, action, setuper);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.warn(`not registered server action. action(${name})`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
setupRaws(expressRoute, setuper) {
|
|
91
|
+
let name = this.meta.getFullname();
|
|
92
|
+
let handles = this.server.getRawByName(name);
|
|
93
|
+
if (Array.isArray(handles)) {
|
|
94
|
+
for (let handle of handles) {
|
|
95
|
+
handle(expressRoute);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
setup(setuper) {
|
|
100
|
+
let pRoute = setuper.factoryExpressRouter(this.meta);
|
|
101
|
+
this.setupActions(pRoute, setuper);
|
|
102
|
+
this.setupRaws(pRoute, setuper);
|
|
103
|
+
for (let dtiRoute of this.meta.getChildroutes()) {
|
|
104
|
+
let lRoute = new DtiServerRoute(dtiRoute, this.server).setup(setuper);
|
|
105
|
+
pRoute.use(dtiRoute.getLocalPath(), lRoute);
|
|
106
|
+
}
|
|
107
|
+
return pRoute;
|
|
108
|
+
}
|
|
109
|
+
}
|
package/esm/server.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DtiRoute } from "@napp/dti-core";
|
|
2
|
+
import { DtiServerAction } from "./action";
|
|
3
|
+
import { OSetupParam } from "./common";
|
|
4
|
+
export interface IRawActionBuilder {
|
|
5
|
+
(expressRoute: any): void;
|
|
6
|
+
}
|
|
7
|
+
export interface ISignatureVerify {
|
|
8
|
+
(data: string): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
export declare class DtiServer {
|
|
11
|
+
private root;
|
|
12
|
+
constructor(root: DtiRoute);
|
|
13
|
+
private _actions;
|
|
14
|
+
private _raws;
|
|
15
|
+
private _signatureSecret;
|
|
16
|
+
register(...actions: DtiServerAction<any, any>[]): this;
|
|
17
|
+
rawRegister(route: DtiRoute, ...handlers: IRawActionBuilder[]): this;
|
|
18
|
+
getActionByName(name: string): DtiServerAction<any, any> | undefined;
|
|
19
|
+
getRawByName(name: string): IRawActionBuilder[] | undefined;
|
|
20
|
+
get signatureSecret(): (() => Promise<string>) | undefined;
|
|
21
|
+
static setup(server: DtiServer, setuper: OSetupParam): any;
|
|
22
|
+
}
|
package/esm/server.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DtiServerRoute } from "./route";
|
|
2
|
+
import { BundlerServer } from "./bundler";
|
|
3
|
+
export class DtiServer {
|
|
4
|
+
root;
|
|
5
|
+
constructor(root) {
|
|
6
|
+
this.root = root;
|
|
7
|
+
}
|
|
8
|
+
_actions = new Map();
|
|
9
|
+
_raws = new Map();
|
|
10
|
+
_signatureSecret = undefined;
|
|
11
|
+
register(...actions) {
|
|
12
|
+
for (let action of actions) {
|
|
13
|
+
let name = action.meta.getFullname();
|
|
14
|
+
if (this._actions.has(name)) {
|
|
15
|
+
throw new Error(`already registed(${name})`);
|
|
16
|
+
}
|
|
17
|
+
this._actions.set(name, action);
|
|
18
|
+
}
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
rawRegister(route, ...handlers) {
|
|
22
|
+
let name = route.getFullname();
|
|
23
|
+
if (this._raws.has(name)) {
|
|
24
|
+
let olds = this._raws.get(name) || [];
|
|
25
|
+
this._raws.set(name, [...olds, ...handlers]);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this._raws.set(name, [...handlers]);
|
|
29
|
+
}
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
getActionByName(name) {
|
|
33
|
+
return this._actions.get(name);
|
|
34
|
+
}
|
|
35
|
+
getRawByName(name) {
|
|
36
|
+
return this._raws.get(name);
|
|
37
|
+
}
|
|
38
|
+
get signatureSecret() {
|
|
39
|
+
return this._signatureSecret;
|
|
40
|
+
}
|
|
41
|
+
static setup(server, setuper) {
|
|
42
|
+
let route = setuper.factoryExpressRouter(server.root);
|
|
43
|
+
new BundlerServer(server).setup(route, setuper);
|
|
44
|
+
route.use(server.root.getLocalPath(), new DtiServerRoute(server.root, server).setup(setuper));
|
|
45
|
+
if (setuper.errorHandle) {
|
|
46
|
+
route.use(setuper.errorHandle);
|
|
47
|
+
}
|
|
48
|
+
server._signatureSecret = setuper.signatureSecret;
|
|
49
|
+
return route;
|
|
50
|
+
}
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napp/dti-server",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.2",
|
|
4
4
|
"description": "data transaction interface server library",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
},
|
|
9
9
|
"types": "index.d.ts",
|
|
10
10
|
"main": "index.js",
|
|
11
|
+
"module": "esm/index.js",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"require": "./index.js",
|
|
15
|
+
"import": "./esm/index.js",
|
|
16
|
+
"types": "./index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
11
19
|
"keywords": [
|
|
12
20
|
"napp",
|
|
13
21
|
"Rest API",
|
|
@@ -19,6 +27,6 @@
|
|
|
19
27
|
"@napp/exception": "^9.1.4"
|
|
20
28
|
},
|
|
21
29
|
"dependencies": {
|
|
22
|
-
"@napp/dti-core": "4.
|
|
30
|
+
"@napp/dti-core": "4.5.2"
|
|
23
31
|
}
|
|
24
32
|
}
|
package/route.js
CHANGED
|
@@ -3,20 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DtiServerRoute = void 0;
|
|
4
4
|
const dti_core_1 = require("@napp/dti-core");
|
|
5
5
|
class DtiServerRoute {
|
|
6
|
+
meta;
|
|
7
|
+
server;
|
|
8
|
+
base62 = new dti_core_1.Base62();
|
|
6
9
|
constructor(meta, server) {
|
|
7
10
|
this.meta = meta;
|
|
8
11
|
this.server = server;
|
|
9
|
-
this.base62 = new dti_core_1.Base62();
|
|
10
12
|
}
|
|
11
13
|
param(action, req) {
|
|
12
|
-
var _a;
|
|
13
14
|
let mode = action.meta.getMode();
|
|
14
15
|
if (mode === dti_core_1.DtiMode.QString) {
|
|
15
16
|
return req.query;
|
|
16
17
|
}
|
|
17
18
|
else if (mode === dti_core_1.DtiMode.QJson) {
|
|
18
19
|
try {
|
|
19
|
-
let p =
|
|
20
|
+
let p = req.query?.p;
|
|
20
21
|
if (p) {
|
|
21
22
|
let json = this.base62.decode(p);
|
|
22
23
|
return JSON.parse(json);
|
|
@@ -31,10 +32,10 @@ class DtiServerRoute {
|
|
|
31
32
|
}
|
|
32
33
|
throw new Error('not supported mode');
|
|
33
34
|
}
|
|
34
|
-
callAction(sa, req, res, next) {
|
|
35
|
+
async callAction(sa, req, res, next) {
|
|
35
36
|
try {
|
|
36
37
|
let param = this.param(sa, req);
|
|
37
|
-
sa.validation(param);
|
|
38
|
+
await sa.validation(this.server, param, req);
|
|
38
39
|
return sa.action(param, { req, res })
|
|
39
40
|
.then(rsu => {
|
|
40
41
|
if (dti_core_1.DtiRawResponse.is(rsu) === false) {
|
|
@@ -50,8 +51,8 @@ class DtiServerRoute {
|
|
|
50
51
|
setupAction(expressRoute, action, setuper) {
|
|
51
52
|
let mode = action.meta.getMode();
|
|
52
53
|
let path = action.meta.getPath();
|
|
53
|
-
let endpoint = (req, res, next) => {
|
|
54
|
-
this.callAction(action, req, res, next);
|
|
54
|
+
let endpoint = async (req, res, next) => {
|
|
55
|
+
await this.callAction(action, req, res, next);
|
|
55
56
|
};
|
|
56
57
|
if (mode === dti_core_1.DtiMode.QString || mode === dti_core_1.DtiMode.QJson) {
|
|
57
58
|
expressRoute.get(path, endpoint);
|
package/server.d.ts
CHANGED
|
@@ -4,14 +4,19 @@ import { OSetupParam } from "./common";
|
|
|
4
4
|
export interface IRawActionBuilder {
|
|
5
5
|
(expressRoute: any): void;
|
|
6
6
|
}
|
|
7
|
+
export interface ISignatureVerify {
|
|
8
|
+
(data: string): Promise<string>;
|
|
9
|
+
}
|
|
7
10
|
export declare class DtiServer {
|
|
8
11
|
private root;
|
|
9
12
|
constructor(root: DtiRoute);
|
|
10
13
|
private _actions;
|
|
11
14
|
private _raws;
|
|
15
|
+
private _signatureSecret;
|
|
12
16
|
register(...actions: DtiServerAction<any, any>[]): this;
|
|
13
17
|
rawRegister(route: DtiRoute, ...handlers: IRawActionBuilder[]): this;
|
|
14
18
|
getActionByName(name: string): DtiServerAction<any, any> | undefined;
|
|
15
19
|
getRawByName(name: string): IRawActionBuilder[] | undefined;
|
|
20
|
+
get signatureSecret(): (() => Promise<string>) | undefined;
|
|
16
21
|
static setup(server: DtiServer, setuper: OSetupParam): any;
|
|
17
22
|
}
|
package/server.js
CHANGED
|
@@ -4,11 +4,13 @@ exports.DtiServer = void 0;
|
|
|
4
4
|
const route_1 = require("./route");
|
|
5
5
|
const bundler_1 = require("./bundler");
|
|
6
6
|
class DtiServer {
|
|
7
|
+
root;
|
|
7
8
|
constructor(root) {
|
|
8
9
|
this.root = root;
|
|
9
|
-
this._actions = new Map();
|
|
10
|
-
this._raws = new Map();
|
|
11
10
|
}
|
|
11
|
+
_actions = new Map();
|
|
12
|
+
_raws = new Map();
|
|
13
|
+
_signatureSecret = undefined;
|
|
12
14
|
register(...actions) {
|
|
13
15
|
for (let action of actions) {
|
|
14
16
|
let name = action.meta.getFullname();
|
|
@@ -36,6 +38,9 @@ class DtiServer {
|
|
|
36
38
|
getRawByName(name) {
|
|
37
39
|
return this._raws.get(name);
|
|
38
40
|
}
|
|
41
|
+
get signatureSecret() {
|
|
42
|
+
return this._signatureSecret;
|
|
43
|
+
}
|
|
39
44
|
static setup(server, setuper) {
|
|
40
45
|
let route = setuper.factoryExpressRouter(server.root);
|
|
41
46
|
new bundler_1.BundlerServer(server).setup(route, setuper);
|
|
@@ -43,6 +48,7 @@ class DtiServer {
|
|
|
43
48
|
if (setuper.errorHandle) {
|
|
44
49
|
route.use(setuper.errorHandle);
|
|
45
50
|
}
|
|
51
|
+
server._signatureSecret = setuper.signatureSecret;
|
|
46
52
|
return route;
|
|
47
53
|
}
|
|
48
54
|
}
|