@napp/dti-client 4.4.5 → 4.5.4
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/builder.d.ts +5 -0
- package/builder.js +8 -0
- package/bundler.d.ts +3 -1
- package/bundler.js +7 -7
- package/caller.d.ts +7 -2
- package/caller.js +56 -4
- package/esm/builder.d.ts +5 -0
- package/esm/builder.js +10 -4
- package/esm/bundler.d.ts +3 -1
- package/esm/bundler.js +10 -8
- package/esm/caller.d.ts +7 -2
- package/esm/caller.js +56 -5
- package/esm/client.js +1 -0
- package/esm/route.js +2 -0
- package/esm/tree.js +4 -0
- package/package.json +2 -2
package/builder.d.ts
CHANGED
|
@@ -10,5 +10,10 @@ export declare class DtiClientBuilder {
|
|
|
10
10
|
getBaseUrl(name: string): string | undefined;
|
|
11
11
|
header(route: DtiRoute, builder: ODtiClientHeaderBuilder): this;
|
|
12
12
|
getHeader(name: string): ODtiClientHeaderBuilder | undefined;
|
|
13
|
+
private signatureSecretResolver;
|
|
14
|
+
signatureSecret(resolver: {
|
|
15
|
+
(): Promise<string>;
|
|
16
|
+
} | undefined): this;
|
|
17
|
+
getSignatureResolver(): (() => Promise<string>) | undefined;
|
|
13
18
|
build(): DtiClient;
|
|
14
19
|
}
|
package/builder.js
CHANGED
|
@@ -7,6 +7,7 @@ class DtiClientBuilder {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
this._baseUrls = new tree_1.TreeNamer("root");
|
|
9
9
|
this._headers = new tree_1.TreeNamer("root");
|
|
10
|
+
this.signatureSecretResolver = undefined;
|
|
10
11
|
}
|
|
11
12
|
baseUrl(route, url) {
|
|
12
13
|
this._baseUrls.set(route.getFullname(), url);
|
|
@@ -30,6 +31,13 @@ class DtiClientBuilder {
|
|
|
30
31
|
}
|
|
31
32
|
return undefined;
|
|
32
33
|
}
|
|
34
|
+
signatureSecret(resolver) {
|
|
35
|
+
this.signatureSecretResolver = resolver;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
getSignatureResolver() {
|
|
39
|
+
return this.signatureSecretResolver;
|
|
40
|
+
}
|
|
33
41
|
build() {
|
|
34
42
|
return new client_1.DtiClient(this);
|
|
35
43
|
}
|
package/bundler.d.ts
CHANGED
package/bundler.js
CHANGED
|
@@ -64,17 +64,17 @@ class DtiClientBandler {
|
|
|
64
64
|
headers["Content-Type"] = "application/json";
|
|
65
65
|
return headers;
|
|
66
66
|
}
|
|
67
|
-
call() {
|
|
67
|
+
call(opt) {
|
|
68
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
69
|
this.validate();
|
|
70
70
|
let method = this.getMethod();
|
|
71
71
|
if (method === 'get') {
|
|
72
|
-
return yield this.callGet();
|
|
72
|
+
return yield this.callGet(opt);
|
|
73
73
|
}
|
|
74
|
-
return yield this.callPost();
|
|
74
|
+
return yield this.callPost(opt);
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
-
callGet() {
|
|
77
|
+
callGet(opt) {
|
|
78
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
79
79
|
try {
|
|
80
80
|
let baseUrl = this.getBase();
|
|
@@ -83,7 +83,7 @@ class DtiClientBandler {
|
|
|
83
83
|
let p = this.base62.encode(JSON.stringify(param));
|
|
84
84
|
let q = new URLSearchParams({ p }).toString();
|
|
85
85
|
let resp = yield (0, cross_fetch_1.fetch)(`${baseUrl}/__bundler_get__?${q}`, {
|
|
86
|
-
method: 'get', headers
|
|
86
|
+
method: 'get', headers, signal: opt === null || opt === void 0 ? void 0 : opt.signal
|
|
87
87
|
});
|
|
88
88
|
return yield (0, errorhandle_1.responseHandle)(resp);
|
|
89
89
|
}
|
|
@@ -92,14 +92,14 @@ class DtiClientBandler {
|
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
callPost() {
|
|
95
|
+
callPost(opt) {
|
|
96
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
97
|
try {
|
|
98
98
|
let baseUrl = this.getBase();
|
|
99
99
|
let param = this.getParam();
|
|
100
100
|
let headers = this.getHeaders();
|
|
101
101
|
let resp = yield (0, cross_fetch_1.fetch)(`${baseUrl}/__bundler_post__`, {
|
|
102
|
-
method: 'post', headers, body: JSON.stringify(param)
|
|
102
|
+
method: 'post', headers, body: JSON.stringify(param), signal: opt === null || opt === void 0 ? void 0 : opt.signal
|
|
103
103
|
});
|
|
104
104
|
return yield (0, errorhandle_1.responseHandle)(resp);
|
|
105
105
|
}
|
package/caller.d.ts
CHANGED
|
@@ -12,8 +12,13 @@ export declare class DtiClientCaller<RESULT, PARAM> {
|
|
|
12
12
|
private getBody;
|
|
13
13
|
private getQeury;
|
|
14
14
|
private getHeaders;
|
|
15
|
+
private signature;
|
|
15
16
|
private getUrl;
|
|
16
17
|
bundler(param: PARAM): BundleMeta<RESULT, PARAM>;
|
|
17
|
-
call(param: PARAM
|
|
18
|
-
|
|
18
|
+
call(param: PARAM, opt?: {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}): Promise<RESULT>;
|
|
21
|
+
callRaw(param: PARAM, opt?: {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}): Promise<Response>;
|
|
19
24
|
}
|
package/caller.js
CHANGED
|
@@ -14,6 +14,24 @@ const dti_core_1 = require("@napp/dti-core");
|
|
|
14
14
|
const cross_fetch_1 = require("cross-fetch");
|
|
15
15
|
const route_1 = require("./route");
|
|
16
16
|
const errorhandle_1 = require("./errorhandle");
|
|
17
|
+
function getRandomInt(min, max) {
|
|
18
|
+
const minCeiled = Math.ceil(min);
|
|
19
|
+
const maxFloored = Math.floor(max);
|
|
20
|
+
// The maximum is exclusive and the minimum is inclusive
|
|
21
|
+
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
|
|
22
|
+
}
|
|
23
|
+
function hmacSignBase64(secret, data) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const enc = new TextEncoder();
|
|
26
|
+
const key = yield crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
27
|
+
const sigBuf = yield crypto.subtle.sign("HMAC", key, enc.encode(data));
|
|
28
|
+
const sigBytes = new Uint8Array(sigBuf);
|
|
29
|
+
// base64 encode
|
|
30
|
+
let bin = "";
|
|
31
|
+
sigBytes.forEach(b => (bin += String.fromCharCode(b)));
|
|
32
|
+
return btoa(bin);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
17
35
|
class DtiClientCaller {
|
|
18
36
|
constructor(meta, builder) {
|
|
19
37
|
this.meta = meta;
|
|
@@ -80,19 +98,39 @@ class DtiClientCaller {
|
|
|
80
98
|
}
|
|
81
99
|
return headers;
|
|
82
100
|
}
|
|
101
|
+
signature(data) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const nonce = '' + getRandomInt(10000, 99999);
|
|
104
|
+
const timestamp = '' + Math.round(Date.now() / 1000);
|
|
105
|
+
const secretResolver = this.builder.getSignatureResolver();
|
|
106
|
+
if (secretResolver) {
|
|
107
|
+
const secret = yield secretResolver();
|
|
108
|
+
if (secret) {
|
|
109
|
+
const signature = yield hmacSignBase64(secret, `${timestamp}.${nonce}.${data}`);
|
|
110
|
+
return {
|
|
111
|
+
nonce, timestamp, signature
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
nonce, timestamp,
|
|
117
|
+
signature: ''
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}
|
|
83
121
|
getUrl() {
|
|
84
122
|
return this.routeClient.buildUrl(this.meta.getPath());
|
|
85
123
|
}
|
|
86
124
|
bundler(param) {
|
|
87
125
|
return { meta: this.meta, param };
|
|
88
126
|
}
|
|
89
|
-
call(param) {
|
|
127
|
+
call(param, opt) {
|
|
90
128
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
let resp = yield this.callRaw(param);
|
|
129
|
+
let resp = yield this.callRaw(param, opt);
|
|
92
130
|
return yield (0, errorhandle_1.responseHandle)(resp);
|
|
93
131
|
});
|
|
94
132
|
}
|
|
95
|
-
callRaw(param) {
|
|
133
|
+
callRaw(param, opt) {
|
|
96
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
135
|
this.validate(param);
|
|
98
136
|
let url = this.getUrl();
|
|
@@ -100,8 +138,22 @@ class DtiClientCaller {
|
|
|
100
138
|
let method = this.getMethod();
|
|
101
139
|
let headers = this.getHeaders(param);
|
|
102
140
|
let body = this.getBody(param);
|
|
141
|
+
const signData = this.meta.sign(param);
|
|
142
|
+
if (signData) {
|
|
143
|
+
const { nonce, signature, timestamp } = yield this.signature(signData);
|
|
144
|
+
if (signature) {
|
|
145
|
+
// console.log('method', method)
|
|
146
|
+
// console.log('------------method', method, this.meta.getFullname())
|
|
147
|
+
// console.log('timestamp', timestamp)
|
|
148
|
+
// console.log('nonce', nonce)
|
|
149
|
+
// console.log('signature', signature)
|
|
150
|
+
headers["X-DTI-Timestamp"] = timestamp;
|
|
151
|
+
headers["X-DTI-Nonce"] = nonce;
|
|
152
|
+
headers["X-DTI-Signature"] = signature;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
103
155
|
return yield (0, cross_fetch_1.fetch)(url + (query ? `?${query}` : ''), {
|
|
104
|
-
method, headers, body
|
|
156
|
+
method, headers, body, signal: opt === null || opt === void 0 ? void 0 : opt.signal
|
|
105
157
|
});
|
|
106
158
|
});
|
|
107
159
|
}
|
package/esm/builder.d.ts
CHANGED
|
@@ -10,5 +10,10 @@ export declare class DtiClientBuilder {
|
|
|
10
10
|
getBaseUrl(name: string): string | undefined;
|
|
11
11
|
header(route: DtiRoute, builder: ODtiClientHeaderBuilder): this;
|
|
12
12
|
getHeader(name: string): ODtiClientHeaderBuilder | undefined;
|
|
13
|
+
private signatureSecretResolver;
|
|
14
|
+
signatureSecret(resolver: {
|
|
15
|
+
(): Promise<string>;
|
|
16
|
+
} | undefined): this;
|
|
17
|
+
getSignatureResolver(): (() => Promise<string>) | undefined;
|
|
13
18
|
build(): DtiClient;
|
|
14
19
|
}
|
package/esm/builder.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { TreeNamer } from "./tree";
|
|
2
2
|
import { DtiClient } from "./client";
|
|
3
3
|
export class DtiClientBuilder {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
this._headers = new TreeNamer("root");
|
|
7
|
-
}
|
|
4
|
+
_baseUrls = new TreeNamer("root");
|
|
5
|
+
_headers = new TreeNamer("root");
|
|
8
6
|
baseUrl(route, url) {
|
|
9
7
|
this._baseUrls.set(route.getFullname(), url);
|
|
10
8
|
return this;
|
|
@@ -27,6 +25,14 @@ export class DtiClientBuilder {
|
|
|
27
25
|
}
|
|
28
26
|
return undefined;
|
|
29
27
|
}
|
|
28
|
+
signatureSecretResolver = undefined;
|
|
29
|
+
signatureSecret(resolver) {
|
|
30
|
+
this.signatureSecretResolver = resolver;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
getSignatureResolver() {
|
|
34
|
+
return this.signatureSecretResolver;
|
|
35
|
+
}
|
|
30
36
|
build() {
|
|
31
37
|
return new DtiClient(this);
|
|
32
38
|
}
|
package/esm/bundler.d.ts
CHANGED
package/esm/bundler.js
CHANGED
|
@@ -3,10 +3,12 @@ import { Exception } from "@napp/exception";
|
|
|
3
3
|
import { fetch } from "cross-fetch";
|
|
4
4
|
import { responseHandle } from "./errorhandle";
|
|
5
5
|
export class DtiClientBandler {
|
|
6
|
+
bundleMetas;
|
|
7
|
+
builder;
|
|
8
|
+
base62 = new Base62();
|
|
6
9
|
constructor(bundleMetas, builder) {
|
|
7
10
|
this.bundleMetas = bundleMetas;
|
|
8
11
|
this.builder = builder;
|
|
9
|
-
this.base62 = new Base62();
|
|
10
12
|
}
|
|
11
13
|
validate() {
|
|
12
14
|
for (let it of this.bundleMetas) {
|
|
@@ -52,15 +54,15 @@ export class DtiClientBandler {
|
|
|
52
54
|
headers["Content-Type"] = "application/json";
|
|
53
55
|
return headers;
|
|
54
56
|
}
|
|
55
|
-
async call() {
|
|
57
|
+
async call(opt) {
|
|
56
58
|
this.validate();
|
|
57
59
|
let method = this.getMethod();
|
|
58
60
|
if (method === 'get') {
|
|
59
|
-
return await this.callGet();
|
|
61
|
+
return await this.callGet(opt);
|
|
60
62
|
}
|
|
61
|
-
return await this.callPost();
|
|
63
|
+
return await this.callPost(opt);
|
|
62
64
|
}
|
|
63
|
-
async callGet() {
|
|
65
|
+
async callGet(opt) {
|
|
64
66
|
try {
|
|
65
67
|
let baseUrl = this.getBase();
|
|
66
68
|
let param = this.getParam();
|
|
@@ -68,7 +70,7 @@ export class DtiClientBandler {
|
|
|
68
70
|
let p = this.base62.encode(JSON.stringify(param));
|
|
69
71
|
let q = new URLSearchParams({ p }).toString();
|
|
70
72
|
let resp = await fetch(`${baseUrl}/__bundler_get__?${q}`, {
|
|
71
|
-
method: 'get', headers
|
|
73
|
+
method: 'get', headers, signal: opt?.signal
|
|
72
74
|
});
|
|
73
75
|
return await responseHandle(resp);
|
|
74
76
|
}
|
|
@@ -76,13 +78,13 @@ export class DtiClientBandler {
|
|
|
76
78
|
throw Exception.from(error);
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
|
-
async callPost() {
|
|
81
|
+
async callPost(opt) {
|
|
80
82
|
try {
|
|
81
83
|
let baseUrl = this.getBase();
|
|
82
84
|
let param = this.getParam();
|
|
83
85
|
let headers = this.getHeaders();
|
|
84
86
|
let resp = await fetch(`${baseUrl}/__bundler_post__`, {
|
|
85
|
-
method: 'post', headers, body: JSON.stringify(param)
|
|
87
|
+
method: 'post', headers, body: JSON.stringify(param), signal: opt?.signal
|
|
86
88
|
});
|
|
87
89
|
return await responseHandle(resp);
|
|
88
90
|
}
|
package/esm/caller.d.ts
CHANGED
|
@@ -12,8 +12,13 @@ export declare class DtiClientCaller<RESULT, PARAM> {
|
|
|
12
12
|
private getBody;
|
|
13
13
|
private getQeury;
|
|
14
14
|
private getHeaders;
|
|
15
|
+
private signature;
|
|
15
16
|
private getUrl;
|
|
16
17
|
bundler(param: PARAM): BundleMeta<RESULT, PARAM>;
|
|
17
|
-
call(param: PARAM
|
|
18
|
-
|
|
18
|
+
call(param: PARAM, opt?: {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}): Promise<RESULT>;
|
|
21
|
+
callRaw(param: PARAM, opt?: {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}): Promise<Response>;
|
|
19
24
|
}
|
package/esm/caller.js
CHANGED
|
@@ -2,11 +2,30 @@ import { DtiMode, Base62 } from "@napp/dti-core";
|
|
|
2
2
|
import { fetch } from "cross-fetch";
|
|
3
3
|
import { DtiClientRoute } from "./route";
|
|
4
4
|
import { responseHandle } from "./errorhandle";
|
|
5
|
+
function getRandomInt(min, max) {
|
|
6
|
+
const minCeiled = Math.ceil(min);
|
|
7
|
+
const maxFloored = Math.floor(max);
|
|
8
|
+
// The maximum is exclusive and the minimum is inclusive
|
|
9
|
+
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
|
|
10
|
+
}
|
|
11
|
+
async function hmacSignBase64(secret, data) {
|
|
12
|
+
const enc = new TextEncoder();
|
|
13
|
+
const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
14
|
+
const sigBuf = await crypto.subtle.sign("HMAC", key, enc.encode(data));
|
|
15
|
+
const sigBytes = new Uint8Array(sigBuf);
|
|
16
|
+
// base64 encode
|
|
17
|
+
let bin = "";
|
|
18
|
+
sigBytes.forEach(b => (bin += String.fromCharCode(b)));
|
|
19
|
+
return btoa(bin);
|
|
20
|
+
}
|
|
5
21
|
export class DtiClientCaller {
|
|
22
|
+
meta;
|
|
23
|
+
builder;
|
|
24
|
+
base62 = new Base62();
|
|
25
|
+
routeClient;
|
|
6
26
|
constructor(meta, builder) {
|
|
7
27
|
this.meta = meta;
|
|
8
28
|
this.builder = builder;
|
|
9
|
-
this.base62 = new Base62();
|
|
10
29
|
this.routeClient = new DtiClientRoute(meta.getRoute(), builder);
|
|
11
30
|
}
|
|
12
31
|
validate(param) {
|
|
@@ -68,25 +87,57 @@ export class DtiClientCaller {
|
|
|
68
87
|
}
|
|
69
88
|
return headers;
|
|
70
89
|
}
|
|
90
|
+
async signature(data) {
|
|
91
|
+
const nonce = '' + getRandomInt(10000, 99999);
|
|
92
|
+
const timestamp = '' + Math.round(Date.now() / 1000);
|
|
93
|
+
const secretResolver = this.builder.getSignatureResolver();
|
|
94
|
+
if (secretResolver) {
|
|
95
|
+
const secret = await secretResolver();
|
|
96
|
+
if (secret) {
|
|
97
|
+
const signature = await hmacSignBase64(secret, `${timestamp}.${nonce}.${data}`);
|
|
98
|
+
return {
|
|
99
|
+
nonce, timestamp, signature
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
nonce, timestamp,
|
|
105
|
+
signature: ''
|
|
106
|
+
};
|
|
107
|
+
}
|
|
71
108
|
getUrl() {
|
|
72
109
|
return this.routeClient.buildUrl(this.meta.getPath());
|
|
73
110
|
}
|
|
74
111
|
bundler(param) {
|
|
75
112
|
return { meta: this.meta, param };
|
|
76
113
|
}
|
|
77
|
-
async call(param) {
|
|
78
|
-
let resp = await this.callRaw(param);
|
|
114
|
+
async call(param, opt) {
|
|
115
|
+
let resp = await this.callRaw(param, opt);
|
|
79
116
|
return await responseHandle(resp);
|
|
80
117
|
}
|
|
81
|
-
async callRaw(param) {
|
|
118
|
+
async callRaw(param, opt) {
|
|
82
119
|
this.validate(param);
|
|
83
120
|
let url = this.getUrl();
|
|
84
121
|
let query = this.getQeury(param);
|
|
85
122
|
let method = this.getMethod();
|
|
86
123
|
let headers = this.getHeaders(param);
|
|
87
124
|
let body = this.getBody(param);
|
|
125
|
+
const signData = this.meta.sign(param);
|
|
126
|
+
if (signData) {
|
|
127
|
+
const { nonce, signature, timestamp } = await this.signature(signData);
|
|
128
|
+
if (signature) {
|
|
129
|
+
// console.log('method', method)
|
|
130
|
+
// console.log('------------method', method, this.meta.getFullname())
|
|
131
|
+
// console.log('timestamp', timestamp)
|
|
132
|
+
// console.log('nonce', nonce)
|
|
133
|
+
// console.log('signature', signature)
|
|
134
|
+
headers["X-DTI-Timestamp"] = timestamp;
|
|
135
|
+
headers["X-DTI-Nonce"] = nonce;
|
|
136
|
+
headers["X-DTI-Signature"] = signature;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
88
139
|
return await fetch(url + (query ? `?${query}` : ''), {
|
|
89
|
-
method, headers, body
|
|
140
|
+
method, headers, body, signal: opt?.signal
|
|
90
141
|
});
|
|
91
142
|
}
|
|
92
143
|
}
|
package/esm/client.js
CHANGED
package/esm/route.js
CHANGED
package/esm/tree.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napp/dti-client",
|
|
3
|
-
"version": "4.4
|
|
3
|
+
"version": "4.5.4",
|
|
4
4
|
"description": "data transaction interface client library",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"author": "Farcek <farcek@gmail.com>",
|
|
25
25
|
"license": "ISC",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@napp/dti-core": "4.4
|
|
27
|
+
"@napp/dti-core": "4.5.4"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@napp/exception": "^9.1.4",
|