@cloudbase/cli 2.0.4 → 2.0.5
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/bin/cloudbase.js +0 -0
- package/bin/tcb.js +0 -0
- package/lib/commands/run/list.js +2 -3
- package/lib/utils/tcbrApi/callTcbrApi.js +2 -2
- package/package.json +2 -2
- package/src/commands/run/list.ts +2 -3
- package/src/utils/tcbrApi/callTcbrApi.ts +1 -1
- package/lib/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.js +0 -268
- package/lib/utils/tcbrApi/tcbr-cloud-api/error.js +0 -17
- package/lib/utils/tcbrApi/tcbr-cloud-api/index.js +0 -17
- package/lib/utils/tcbrApi/tcbr-cloud-api/request.js +0 -40
- package/lib/utils/tcbrApi/tcbr-cloud-api-request.js +0 -61
- package/src/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.ts +0 -363
- package/src/utils/tcbrApi/tcbr-cloud-api/error.ts +0 -30
- package/src/utils/tcbrApi/tcbr-cloud-api/index.ts +0 -1
- package/src/utils/tcbrApi/tcbr-cloud-api/request.ts +0 -28
- package/src/utils/tcbrApi/tcbr-cloud-api-request.ts +0 -66
- package/types/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.d.ts +0 -51
- package/types/utils/tcbrApi/tcbr-cloud-api/error.d.ts +0 -20
- package/types/utils/tcbrApi/tcbr-cloud-api/index.d.ts +0 -1
- package/types/utils/tcbrApi/tcbr-cloud-api/request.d.ts +0 -4
- package/types/utils/tcbrApi/tcbr-cloud-api-request.d.ts +0 -9
package/bin/cloudbase.js
CHANGED
|
File without changes
|
package/bin/tcb.js
CHANGED
|
File without changes
|
package/lib/commands/run/list.js
CHANGED
|
@@ -27,7 +27,6 @@ const error_1 = require("../../error");
|
|
|
27
27
|
const run_1 = require("../../run");
|
|
28
28
|
const utils_1 = require("../../utils");
|
|
29
29
|
const decorators_1 = require("../../decorators");
|
|
30
|
-
const utils_2 = require("../../utils");
|
|
31
30
|
const StatusMap = {
|
|
32
31
|
succ: '正常'
|
|
33
32
|
};
|
|
@@ -55,9 +54,9 @@ let ListRun = class ListRun extends common_1.Command {
|
|
|
55
54
|
}
|
|
56
55
|
execute(envId, options) {
|
|
57
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
let envCheckType = yield (0,
|
|
57
|
+
let envCheckType = yield (0, utils_1.checkTcbrEnv)(options.envId, false);
|
|
59
58
|
if (envCheckType !== 0) {
|
|
60
|
-
(0,
|
|
59
|
+
(0, utils_1.logEnvCheck)(envId, envCheckType);
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
63
62
|
let { limit = 20, offset = 0 } = options;
|
|
@@ -11,8 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.callTcbrApi = void 0;
|
|
13
13
|
const toolbox_1 = require("@cloudbase/toolbox");
|
|
14
|
-
const
|
|
15
|
-
const tcbrService =
|
|
14
|
+
const net_1 = require("../net");
|
|
15
|
+
const tcbrService = net_1.CloudApiService.getInstance('tcbr');
|
|
16
16
|
function callTcbrApi(action, data) {
|
|
17
17
|
return __awaiter(this, void 0, void 0, function* () {
|
|
18
18
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "cli tool for cloudbase",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"author": "cwuyiqing@gmail.com",
|
|
30
30
|
"license": "ISC",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@cloudbase/cloud-api": "^0.
|
|
32
|
+
"@cloudbase/cloud-api": "^0.5.3",
|
|
33
33
|
"@cloudbase/framework-core": "^1.6.1",
|
|
34
34
|
"@cloudbase/lowcode-cli": "^0.13.2",
|
|
35
35
|
"@cloudbase/manager-node": "4.0.0",
|
package/src/commands/run/list.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Command, ICommand } from '../common'
|
|
2
2
|
import { CloudBaseError } from '../../error'
|
|
3
|
-
import { listRun
|
|
4
|
-
import { printHorizontalTable, loadingFactory } from '../../utils'
|
|
3
|
+
import { listRun } from '../../run'
|
|
4
|
+
import { printHorizontalTable, loadingFactory, checkTcbrEnv, logEnvCheck} from '../../utils'
|
|
5
5
|
import { InjectParams, EnvId, ArgsOptions } from '../../decorators'
|
|
6
|
-
import { checkTcbrEnv, logEnvCheck } from '../../utils'
|
|
7
6
|
import { EnumEnvCheck } from '../../constant'
|
|
8
7
|
|
|
9
8
|
const StatusMap = {
|
|
@@ -1,268 +0,0 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.CloudApiService = exports.nodeFetch = exports.fetchStream = exports.fetch = void 0;
|
|
16
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
17
|
-
const url_1 = require("url");
|
|
18
|
-
const query_string_1 = __importDefault(require("query-string"));
|
|
19
|
-
const request_1 = require("./request");
|
|
20
|
-
const error_1 = require("./error");
|
|
21
|
-
function isObject(x) {
|
|
22
|
-
return typeof x === 'object' && !Array.isArray(x) && x !== null;
|
|
23
|
-
}
|
|
24
|
-
function deepRemoveVoid(obj) {
|
|
25
|
-
if (Array.isArray(obj)) {
|
|
26
|
-
return obj.map(deepRemoveVoid);
|
|
27
|
-
}
|
|
28
|
-
else if (isObject(obj)) {
|
|
29
|
-
let result = {};
|
|
30
|
-
for (const key in obj) {
|
|
31
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
32
|
-
const value = obj[key];
|
|
33
|
-
if (typeof value !== 'undefined' && value !== null) {
|
|
34
|
-
result[key] = deepRemoveVoid(value);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return result;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
return obj;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function sha256(message, secret, encoding) {
|
|
45
|
-
const hmac = crypto_1.default.createHmac('sha256', secret);
|
|
46
|
-
return hmac.update(message).digest(encoding);
|
|
47
|
-
}
|
|
48
|
-
function getHash(message) {
|
|
49
|
-
const hash = crypto_1.default.createHash('sha256');
|
|
50
|
-
return hash.update(message).digest('hex');
|
|
51
|
-
}
|
|
52
|
-
function getDate(timestamp) {
|
|
53
|
-
const date = new Date(timestamp * 1000);
|
|
54
|
-
const year = date.getUTCFullYear();
|
|
55
|
-
const month = ('0' + (date.getUTCMonth() + 1)).slice(-2);
|
|
56
|
-
const day = ('0' + date.getUTCDate()).slice(-2);
|
|
57
|
-
return `${year}-${month}-${day}`;
|
|
58
|
-
}
|
|
59
|
-
const ServiceVersionMap = {
|
|
60
|
-
tcb: '2018-06-08',
|
|
61
|
-
scf: '2018-04-16',
|
|
62
|
-
flexdb: '2018-11-27',
|
|
63
|
-
cam: '2019-01-16',
|
|
64
|
-
vpc: '2017-03-12',
|
|
65
|
-
ssl: '2019-12-05',
|
|
66
|
-
tcbr: '2022-02-17',
|
|
67
|
-
};
|
|
68
|
-
exports.fetch = request_1.fetch;
|
|
69
|
-
exports.fetchStream = request_1.fetchStream;
|
|
70
|
-
exports.nodeFetch = request_1.nodeFetch;
|
|
71
|
-
const isTokenExpired = (credential, gap = 120) => credential.tokenExpired && Number(credential.tokenExpired) < Date.now() + gap * 1000;
|
|
72
|
-
class CloudApiService {
|
|
73
|
-
constructor(options) {
|
|
74
|
-
if (!options) {
|
|
75
|
-
throw new error_1.CloudBaseError('Options cloud not be empty!');
|
|
76
|
-
}
|
|
77
|
-
const { service, baseParams, version, proxy, region, credential, getCredential, timeout = 60000 } = options;
|
|
78
|
-
this.service = service;
|
|
79
|
-
this.timeout = timeout;
|
|
80
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_PROXY) {
|
|
81
|
-
this.proxy = process.env.CLOUDBASE_TCB_CLOUDAPI_PROXY;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
this.proxy = proxy;
|
|
85
|
-
}
|
|
86
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_REGION) {
|
|
87
|
-
this.region = process.env.CLOUDBASE_TCB_CLOUDAPI_REGION;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.region = region || process.env.TENCENTCLOUD_REGION || 'ap-shanghai';
|
|
91
|
-
}
|
|
92
|
-
this.credential = credential;
|
|
93
|
-
this.baseParams = baseParams || {};
|
|
94
|
-
this.getCredential = getCredential;
|
|
95
|
-
this.version = ServiceVersionMap[service] || version;
|
|
96
|
-
}
|
|
97
|
-
static getInstance(options) {
|
|
98
|
-
var _a;
|
|
99
|
-
const { service } = options;
|
|
100
|
-
if ((_a = CloudApiService.serviceCacheMap) === null || _a === void 0 ? void 0 : _a[service]) {
|
|
101
|
-
return CloudApiService.serviceCacheMap[service];
|
|
102
|
-
}
|
|
103
|
-
const apiService = new CloudApiService(options);
|
|
104
|
-
CloudApiService.serviceCacheMap = Object.assign({}, CloudApiService.serviceCacheMap);
|
|
105
|
-
CloudApiService.serviceCacheMap[service] = apiService;
|
|
106
|
-
return apiService;
|
|
107
|
-
}
|
|
108
|
-
get baseUrl() {
|
|
109
|
-
const urlMap = {
|
|
110
|
-
tcb: 'https://tcb.tencentcloudapi.com',
|
|
111
|
-
flexdb: 'https://flexdb.tencentcloudapi.com',
|
|
112
|
-
lowcode: `${process.env.CLOUDBASE_LOWCODE_ENDPOINT || 'https://lcap.cloud.tencent.com'}/api/v1/cliapi`,
|
|
113
|
-
tcbr: 'https://tcbr.tencentcloudapi.com',
|
|
114
|
-
};
|
|
115
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_HOST) {
|
|
116
|
-
return `http://${process.env.CLOUDBASE_TCB_CLOUDAPI_HOST}`;
|
|
117
|
-
}
|
|
118
|
-
if (urlMap[this.service]) {
|
|
119
|
-
return urlMap[this.service];
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
return `https://${this.service}.tencentcloudapi.com`;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
request(actionOrOptions, assignData = {}, assignMethod = 'POST') {
|
|
126
|
-
var _a;
|
|
127
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
-
let action;
|
|
129
|
-
let data;
|
|
130
|
-
let method;
|
|
131
|
-
let region;
|
|
132
|
-
if (typeof actionOrOptions === 'string') {
|
|
133
|
-
action = actionOrOptions;
|
|
134
|
-
data = assignData;
|
|
135
|
-
method = assignMethod;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
action = actionOrOptions === null || actionOrOptions === void 0 ? void 0 : actionOrOptions.action;
|
|
139
|
-
data = (actionOrOptions === null || actionOrOptions === void 0 ? void 0 : actionOrOptions.data) || {};
|
|
140
|
-
method = (actionOrOptions === null || actionOrOptions === void 0 ? void 0 : actionOrOptions.method) || 'POST';
|
|
141
|
-
region = actionOrOptions === null || actionOrOptions === void 0 ? void 0 : actionOrOptions.region;
|
|
142
|
-
}
|
|
143
|
-
this.action = action;
|
|
144
|
-
this.data = deepRemoveVoid(Object.assign(Object.assign({}, data), this.baseParams));
|
|
145
|
-
this.method = method;
|
|
146
|
-
this.url = this.baseUrl;
|
|
147
|
-
if (!((_a = this.credential) === null || _a === void 0 ? void 0 : _a.secretId) || isTokenExpired(this.credential)) {
|
|
148
|
-
if (!this.getCredential) {
|
|
149
|
-
throw new error_1.CloudBaseError('You must provide credential info!');
|
|
150
|
-
}
|
|
151
|
-
if (typeof this.getCredential !== 'function') {
|
|
152
|
-
throw new error_1.CloudBaseError('The getCredential option must be a function!');
|
|
153
|
-
}
|
|
154
|
-
const credential = yield this.getCredential();
|
|
155
|
-
if (!credential) {
|
|
156
|
-
throw new error_1.CloudBaseError('Calling getCredential function get no credential info!');
|
|
157
|
-
}
|
|
158
|
-
this.credential = credential;
|
|
159
|
-
}
|
|
160
|
-
try {
|
|
161
|
-
const data = yield this.requestWithSign(region);
|
|
162
|
-
if (data.Response.Error) {
|
|
163
|
-
const tcError = new error_1.CloudBaseError(data.Response.Error.Message, {
|
|
164
|
-
action,
|
|
165
|
-
requestId: data.Response.RequestId,
|
|
166
|
-
code: data.Response.Error.Code,
|
|
167
|
-
original: data.Response.Error
|
|
168
|
-
});
|
|
169
|
-
throw tcError;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
return data.Response;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch (e) {
|
|
176
|
-
if (e.name === 'CloudBaseError') {
|
|
177
|
-
throw e;
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
throw new error_1.CloudBaseError(e.message, {
|
|
181
|
-
action,
|
|
182
|
-
code: e.code,
|
|
183
|
-
type: e.type
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
requestWithSign(region) {
|
|
190
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
191
|
-
const timestamp = Math.floor(Date.now() / 1000);
|
|
192
|
-
const { method, timeout, data } = this;
|
|
193
|
-
if (method === 'GET') {
|
|
194
|
-
this.url += '?' + query_string_1.default.stringify(data);
|
|
195
|
-
}
|
|
196
|
-
if (method === 'POST') {
|
|
197
|
-
this.payload = data;
|
|
198
|
-
}
|
|
199
|
-
const { CLOUDBASE_TCB_CLOUDAPI_HOST } = process.env;
|
|
200
|
-
if (this.service === 'tcb' && CLOUDBASE_TCB_CLOUDAPI_HOST) {
|
|
201
|
-
this.host = CLOUDBASE_TCB_CLOUDAPI_HOST;
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
this.host = new url_1.URL(this.url).host;
|
|
205
|
-
}
|
|
206
|
-
const config = {
|
|
207
|
-
method,
|
|
208
|
-
timeout,
|
|
209
|
-
headers: {
|
|
210
|
-
Host: this.host,
|
|
211
|
-
'X-TC-Action': this.action,
|
|
212
|
-
'X-TC-Region': region || this.region,
|
|
213
|
-
'X-TC-Timestamp': timestamp,
|
|
214
|
-
'X-TC-Version': this.version
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
if (this.credential.token) {
|
|
218
|
-
config.headers['X-TC-Token'] = this.credential.token;
|
|
219
|
-
}
|
|
220
|
-
if (method === 'GET') {
|
|
221
|
-
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
222
|
-
}
|
|
223
|
-
if (method === 'POST') {
|
|
224
|
-
config.body = JSON.stringify(data);
|
|
225
|
-
config.headers['Content-Type'] = 'application/json';
|
|
226
|
-
}
|
|
227
|
-
const sign = this.getRequestSign(timestamp);
|
|
228
|
-
config.headers['Authorization'] = sign;
|
|
229
|
-
return (0, exports.fetch)(this.url, config, this.proxy);
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
getRequestSign(timestamp) {
|
|
233
|
-
const { method, url, service } = this;
|
|
234
|
-
const { secretId, secretKey } = this.credential;
|
|
235
|
-
const urlObj = new url_1.URL(url);
|
|
236
|
-
let headers = '';
|
|
237
|
-
const signedHeaders = 'content-type;host';
|
|
238
|
-
if (method === 'GET') {
|
|
239
|
-
headers = 'content-type:application/x-www-form-urlencoded\n';
|
|
240
|
-
}
|
|
241
|
-
if (method === 'POST') {
|
|
242
|
-
headers = 'content-type:application/json\n';
|
|
243
|
-
}
|
|
244
|
-
let path = urlObj.pathname;
|
|
245
|
-
if (path === '/api/v1/cliapi' && service === 'lowcode') {
|
|
246
|
-
path = '//lcap.cloud.tencent.com/api/v1/cliapi';
|
|
247
|
-
headers += 'host:lcap.cloud.tencent.com\n';
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
headers += `host:${this.host}\n`;
|
|
251
|
-
}
|
|
252
|
-
const querystring = urlObj.search.slice(1);
|
|
253
|
-
const payloadHash = this.payload ? getHash(JSON.stringify(this.payload)) : getHash('');
|
|
254
|
-
const canonicalRequest = `${method}\n${path}\n${querystring}\n${headers}\n${signedHeaders}\n${payloadHash}`;
|
|
255
|
-
const date = getDate(timestamp);
|
|
256
|
-
const StringToSign = `TC3-HMAC-SHA256\n${timestamp}\n${date}/${service}/tc3_request\n${getHash(canonicalRequest)}`;
|
|
257
|
-
const kDate = sha256(date, `TC3${secretKey}`);
|
|
258
|
-
const kService = sha256(service, kDate);
|
|
259
|
-
const kSigning = sha256('tc3_request', kService);
|
|
260
|
-
const signature = sha256(StringToSign, kSigning, 'hex');
|
|
261
|
-
return `TC3-HMAC-SHA256 Credential=${secretId}/${date}/${service}/tc3_request, SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
262
|
-
}
|
|
263
|
-
clearCredentialCache() {
|
|
264
|
-
this.credential = null;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
exports.CloudApiService = CloudApiService;
|
|
268
|
-
CloudApiService.serviceCacheMap = {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CloudBaseError = void 0;
|
|
4
|
-
class CloudBaseError extends Error {
|
|
5
|
-
constructor(message, options = {}) {
|
|
6
|
-
super();
|
|
7
|
-
this.name = 'CloudBaseError';
|
|
8
|
-
const { code = '', action = '', original = null, requestId = '', type } = options;
|
|
9
|
-
this.message = `[${action}]\nRequestId:${requestId}\n${message}`;
|
|
10
|
-
this.original = original;
|
|
11
|
-
this.code = code;
|
|
12
|
-
this.requestId = requestId;
|
|
13
|
-
this.action = action;
|
|
14
|
-
this.type = type;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.CloudBaseError = CloudBaseError;
|
|
@@ -1,17 +0,0 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./cloud-api-service"), exports);
|
|
@@ -1,40 +0,0 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.fetchStream = exports.fetch = exports.nodeFetch = void 0;
|
|
16
|
-
const url_1 = require("url");
|
|
17
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
18
|
-
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
19
|
-
exports.nodeFetch = node_fetch_1.default;
|
|
20
|
-
function fetch(url, config = {}, proxy = '') {
|
|
21
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
if (proxy) {
|
|
23
|
-
config.agent = new https_proxy_agent_1.HttpsProxyAgent(proxy);
|
|
24
|
-
}
|
|
25
|
-
const escapeUrl = new url_1.URL(url).toString();
|
|
26
|
-
const res = yield (0, node_fetch_1.default)(escapeUrl, config);
|
|
27
|
-
return res.json();
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
exports.fetch = fetch;
|
|
31
|
-
function fetchStream(url, config = {}, proxy = '') {
|
|
32
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
-
if (proxy) {
|
|
34
|
-
config.agent = new https_proxy_agent_1.HttpsProxyAgent(proxy);
|
|
35
|
-
}
|
|
36
|
-
const escapeUrl = new url_1.URL(url).toString();
|
|
37
|
-
return (0, node_fetch_1.default)(escapeUrl, config);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
exports.fetchStream = fetchStream;
|
|
@@ -1,61 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.CloudApiService = void 0;
|
|
13
|
-
const toolbox_1 = require("@cloudbase/toolbox");
|
|
14
|
-
const index_1 = require("./tcbr-cloud-api/index");
|
|
15
|
-
const error_1 = require("../../error");
|
|
16
|
-
const constant_1 = require("../../constant");
|
|
17
|
-
let commonCredential;
|
|
18
|
-
const isTokenExpired = (credential, gap = 120) => credential.accessTokenExpired && Number(credential.accessTokenExpired) < Date.now() + gap * 1000;
|
|
19
|
-
class CloudApiService {
|
|
20
|
-
constructor(service, baseParams, version = '') {
|
|
21
|
-
this.apiService = new index_1.CloudApiService({
|
|
22
|
-
service,
|
|
23
|
-
version: service === 'tcr'
|
|
24
|
-
? version
|
|
25
|
-
: service === 'tcbr'
|
|
26
|
-
? '2022-02-17'
|
|
27
|
-
: '2019-09-24',
|
|
28
|
-
baseParams,
|
|
29
|
-
proxy: (0, toolbox_1.getProxy)(),
|
|
30
|
-
timeout: constant_1.REQUEST_TIMEOUT,
|
|
31
|
-
getCredential: () => __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
if ((commonCredential === null || commonCredential === void 0 ? void 0 : commonCredential.secretId) && !isTokenExpired(commonCredential)) {
|
|
33
|
-
return commonCredential;
|
|
34
|
-
}
|
|
35
|
-
const credential = yield (0, toolbox_1.getCredentialWithoutCheck)();
|
|
36
|
-
if (!credential) {
|
|
37
|
-
throw new error_1.CloudBaseError('无有效身份信息,请使用 cloudbase login 登录');
|
|
38
|
-
}
|
|
39
|
-
commonCredential = credential;
|
|
40
|
-
return Object.assign(Object.assign({}, credential), { tokenExpired: Number(credential.accessTokenExpired) });
|
|
41
|
-
})
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
static getInstance(service) {
|
|
45
|
-
var _a;
|
|
46
|
-
if ((_a = CloudApiService.serviceCacheMap) === null || _a === void 0 ? void 0 : _a[service]) {
|
|
47
|
-
return CloudApiService.serviceCacheMap[service];
|
|
48
|
-
}
|
|
49
|
-
const apiService = new CloudApiService(service);
|
|
50
|
-
CloudApiService.serviceCacheMap[service] = apiService;
|
|
51
|
-
return apiService;
|
|
52
|
-
}
|
|
53
|
-
request(action, data = {}, method = 'POST') {
|
|
54
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
const region = this.region || (yield (0, toolbox_1.getRegion)());
|
|
56
|
-
return this.apiService.request({ action, data, method, region });
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
exports.CloudApiService = CloudApiService;
|
|
61
|
-
CloudApiService.serviceCacheMap = {};
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
import { URL } from 'url'
|
|
3
|
-
import QueryString from 'query-string'
|
|
4
|
-
|
|
5
|
-
import { fetch as _fetch, fetchStream as _fetchStream, nodeFetch as _nodeFetch } from './request'
|
|
6
|
-
import { CloudBaseError } from './error'
|
|
7
|
-
|
|
8
|
-
function isObject(x) {
|
|
9
|
-
return typeof x === 'object' && !Array.isArray(x) && x !== null
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 移除对象中的空值,防止调用云 API 失败
|
|
13
|
-
function deepRemoveVoid(obj) {
|
|
14
|
-
if (Array.isArray(obj)) {
|
|
15
|
-
return obj.map(deepRemoveVoid)
|
|
16
|
-
} else if (isObject(obj)) {
|
|
17
|
-
let result = {}
|
|
18
|
-
for (const key in obj) {
|
|
19
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
20
|
-
const value = obj[key]
|
|
21
|
-
if (typeof value !== 'undefined' && value !== null) {
|
|
22
|
-
result[key] = deepRemoveVoid(value)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return result
|
|
27
|
-
} else {
|
|
28
|
-
return obj
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type HexBase64Latin1Encoding = 'latin1' | 'hex' | 'base64';
|
|
33
|
-
|
|
34
|
-
function sha256(message: string, secret: string, encoding?: HexBase64Latin1Encoding) {
|
|
35
|
-
const hmac = crypto.createHmac('sha256', secret)
|
|
36
|
-
return hmac.update(message).digest(encoding)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getHash(message: string): string {
|
|
40
|
-
const hash = crypto.createHash('sha256')
|
|
41
|
-
return hash.update(message).digest('hex')
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getDate(timestamp: number): string {
|
|
45
|
-
const date = new Date(timestamp * 1000)
|
|
46
|
-
const year = date.getUTCFullYear()
|
|
47
|
-
const month = ('0' + (date.getUTCMonth() + 1)).slice(-2)
|
|
48
|
-
// UTC 日期,非本地时间
|
|
49
|
-
const day = ('0' + date.getUTCDate()).slice(-2)
|
|
50
|
-
return `${year}-${month}-${day}`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const ServiceVersionMap = {
|
|
54
|
-
tcb: '2018-06-08',
|
|
55
|
-
scf: '2018-04-16',
|
|
56
|
-
flexdb: '2018-11-27',
|
|
57
|
-
cam: '2019-01-16',
|
|
58
|
-
vpc: '2017-03-12',
|
|
59
|
-
ssl: '2019-12-05',
|
|
60
|
-
tcbr: '2022-02-17',
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface ServiceOptions {
|
|
64
|
-
service: string;
|
|
65
|
-
version?: string;
|
|
66
|
-
proxy?: string;
|
|
67
|
-
timeout?: number;
|
|
68
|
-
region?: string;
|
|
69
|
-
baseParams?: Record<string, any>;
|
|
70
|
-
credential?: Credential;
|
|
71
|
-
getCredential?: () => Promise<Credential> | Credential;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface Credential {
|
|
75
|
-
secretId: string;
|
|
76
|
-
secretKey: string;
|
|
77
|
-
token?: string;
|
|
78
|
-
tokenExpired?: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface RequestOptions {
|
|
82
|
-
action: string;
|
|
83
|
-
data?: Record<string, any>;
|
|
84
|
-
method?: 'POST' | 'GET';
|
|
85
|
-
region?: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export const fetch = _fetch
|
|
89
|
-
export const fetchStream = _fetchStream
|
|
90
|
-
export const nodeFetch = _nodeFetch
|
|
91
|
-
|
|
92
|
-
// token 将在 n 分钟内过期
|
|
93
|
-
const isTokenExpired = (credential: Credential, gap = 120) =>
|
|
94
|
-
credential.tokenExpired && Number(credential.tokenExpired) < Date.now() + gap * 1000
|
|
95
|
-
|
|
96
|
-
export class CloudApiService {
|
|
97
|
-
// 缓存请求实例
|
|
98
|
-
static serviceCacheMap: Record<string, CloudApiService> = {};
|
|
99
|
-
|
|
100
|
-
static getInstance(options: ServiceOptions) {
|
|
101
|
-
const { service } = options
|
|
102
|
-
if (CloudApiService.serviceCacheMap?.[service]) {
|
|
103
|
-
return CloudApiService.serviceCacheMap[service]
|
|
104
|
-
}
|
|
105
|
-
const apiService = new CloudApiService(options)
|
|
106
|
-
// 预防 serviceCacheMap 被置空导致的错误
|
|
107
|
-
CloudApiService.serviceCacheMap = {
|
|
108
|
-
...CloudApiService.serviceCacheMap
|
|
109
|
-
}
|
|
110
|
-
CloudApiService.serviceCacheMap[service] = apiService
|
|
111
|
-
return apiService
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
service: string;
|
|
115
|
-
version: string;
|
|
116
|
-
proxy: string;
|
|
117
|
-
timeout: number;
|
|
118
|
-
region: string;
|
|
119
|
-
credential: Credential;
|
|
120
|
-
baseParams: Record<string, any>;
|
|
121
|
-
getCredential: () => Promise<Credential> | Credential;
|
|
122
|
-
|
|
123
|
-
url: string;
|
|
124
|
-
host: string;
|
|
125
|
-
action: string;
|
|
126
|
-
method: 'POST' | 'GET';
|
|
127
|
-
data: Record<string, any>;
|
|
128
|
-
payload: Record<string, any>;
|
|
129
|
-
|
|
130
|
-
constructor(options: ServiceOptions) {
|
|
131
|
-
if (!options) {
|
|
132
|
-
throw new CloudBaseError('Options cloud not be empty!')
|
|
133
|
-
}
|
|
134
|
-
const {
|
|
135
|
-
service,
|
|
136
|
-
baseParams,
|
|
137
|
-
version,
|
|
138
|
-
proxy,
|
|
139
|
-
region,
|
|
140
|
-
credential,
|
|
141
|
-
getCredential,
|
|
142
|
-
timeout = 60000
|
|
143
|
-
} = options
|
|
144
|
-
|
|
145
|
-
this.service = service
|
|
146
|
-
this.timeout = timeout
|
|
147
|
-
|
|
148
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_PROXY) {
|
|
149
|
-
this.proxy = process.env.CLOUDBASE_TCB_CLOUDAPI_PROXY
|
|
150
|
-
} else {
|
|
151
|
-
this.proxy = proxy
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_REGION) {
|
|
155
|
-
this.region = process.env.CLOUDBASE_TCB_CLOUDAPI_REGION
|
|
156
|
-
} else {
|
|
157
|
-
this.region = region || process.env.TENCENTCLOUD_REGION || 'ap-shanghai'
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
this.credential = credential
|
|
161
|
-
this.baseParams = baseParams || {}
|
|
162
|
-
this.getCredential = getCredential
|
|
163
|
-
this.version = ServiceVersionMap[service] || version
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
get baseUrl() {
|
|
167
|
-
const urlMap = {
|
|
168
|
-
tcb: 'https://tcb.tencentcloudapi.com',
|
|
169
|
-
flexdb: 'https://flexdb.tencentcloudapi.com',
|
|
170
|
-
lowcode: `${process.env.CLOUDBASE_LOWCODE_ENDPOINT || 'https://lcap.cloud.tencent.com' }/api/v1/cliapi`,
|
|
171
|
-
tcbr: 'https://tcbr.tencentcloudapi.com',
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (this.service === 'tcb' && process.env.CLOUDBASE_TCB_CLOUDAPI_HOST) {
|
|
175
|
-
return `http://${process.env.CLOUDBASE_TCB_CLOUDAPI_HOST}`
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (urlMap[this.service]) {
|
|
179
|
-
return urlMap[this.service]
|
|
180
|
-
} else {
|
|
181
|
-
return `https://${this.service}.tencentcloudapi.com`
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// overload
|
|
186
|
-
async request(options: RequestOptions);
|
|
187
|
-
async request(action: string, data?: Record<string, any>, method?: 'POST' | 'GET');
|
|
188
|
-
|
|
189
|
-
async request(
|
|
190
|
-
actionOrOptions: string | RequestOptions,
|
|
191
|
-
assignData: Record<string, any> = {},
|
|
192
|
-
assignMethod: 'POST' | 'GET' = 'POST'
|
|
193
|
-
) {
|
|
194
|
-
// 增加 region 参数,兼容之前的入参形式
|
|
195
|
-
let action
|
|
196
|
-
let data
|
|
197
|
-
let method
|
|
198
|
-
let region
|
|
199
|
-
if (typeof actionOrOptions === 'string') {
|
|
200
|
-
action = actionOrOptions
|
|
201
|
-
data = assignData
|
|
202
|
-
method = assignMethod
|
|
203
|
-
} else {
|
|
204
|
-
action = actionOrOptions?.action
|
|
205
|
-
data = actionOrOptions?.data || {}
|
|
206
|
-
method = actionOrOptions?.method || 'POST'
|
|
207
|
-
region = actionOrOptions?.region
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
this.action = action
|
|
211
|
-
this.data = deepRemoveVoid({ ...data, ...this.baseParams })
|
|
212
|
-
this.method = method
|
|
213
|
-
|
|
214
|
-
this.url = this.baseUrl
|
|
215
|
-
|
|
216
|
-
// 不存在密钥,或临时密钥过期
|
|
217
|
-
if (!this.credential?.secretId || isTokenExpired(this.credential)) {
|
|
218
|
-
if (!this.getCredential) {
|
|
219
|
-
throw new CloudBaseError('You must provide credential info!')
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (typeof this.getCredential !== 'function') {
|
|
223
|
-
throw new CloudBaseError('The getCredential option must be a function!')
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const credential = await this.getCredential()
|
|
227
|
-
|
|
228
|
-
if (!credential) {
|
|
229
|
-
throw new CloudBaseError('Calling getCredential function get no credential info!')
|
|
230
|
-
}
|
|
231
|
-
this.credential = credential
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
const data: Record<string, any> = await this.requestWithSign(region)
|
|
236
|
-
if (data.Response.Error) {
|
|
237
|
-
const tcError = new CloudBaseError(data.Response.Error.Message, {
|
|
238
|
-
action,
|
|
239
|
-
requestId: data.Response.RequestId,
|
|
240
|
-
code: data.Response.Error.Code,
|
|
241
|
-
original: data.Response.Error
|
|
242
|
-
})
|
|
243
|
-
throw tcError
|
|
244
|
-
} else {
|
|
245
|
-
return data.Response
|
|
246
|
-
}
|
|
247
|
-
} catch (e) {
|
|
248
|
-
// throw e
|
|
249
|
-
if (e.name === 'CloudBaseError') {
|
|
250
|
-
throw e
|
|
251
|
-
} else {
|
|
252
|
-
throw new CloudBaseError(e.message, {
|
|
253
|
-
action,
|
|
254
|
-
code: e.code,
|
|
255
|
-
type: e.type
|
|
256
|
-
})
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
async requestWithSign(region) {
|
|
262
|
-
// data 中可能带有 readStream,由于需要计算整个 body 的 hash,
|
|
263
|
-
// 所以这里把 readStream 转为 Buffer
|
|
264
|
-
// await convertReadStreamToBuffer(data)
|
|
265
|
-
const timestamp = Math.floor(Date.now() / 1000)
|
|
266
|
-
|
|
267
|
-
const { method, timeout, data } = this
|
|
268
|
-
|
|
269
|
-
if (method === 'GET') {
|
|
270
|
-
this.url += '?' + QueryString.stringify(data)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (method === 'POST') {
|
|
274
|
-
this.payload = data
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const { CLOUDBASE_TCB_CLOUDAPI_HOST } = process.env
|
|
278
|
-
|
|
279
|
-
if (this.service === 'tcb' && CLOUDBASE_TCB_CLOUDAPI_HOST) {
|
|
280
|
-
this.host = CLOUDBASE_TCB_CLOUDAPI_HOST
|
|
281
|
-
} else {
|
|
282
|
-
this.host = new URL(this.url).host
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const config: any = {
|
|
286
|
-
method,
|
|
287
|
-
timeout,
|
|
288
|
-
headers: {
|
|
289
|
-
Host: this.host,
|
|
290
|
-
'X-TC-Action': this.action,
|
|
291
|
-
'X-TC-Region': region || this.region,
|
|
292
|
-
'X-TC-Timestamp': timestamp,
|
|
293
|
-
'X-TC-Version': this.version
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (this.credential.token) {
|
|
298
|
-
config.headers['X-TC-Token'] = this.credential.token
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (method === 'GET') {
|
|
302
|
-
config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
303
|
-
}
|
|
304
|
-
if (method === 'POST') {
|
|
305
|
-
config.body = JSON.stringify(data)
|
|
306
|
-
config.headers['Content-Type'] = 'application/json'
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const sign = this.getRequestSign(timestamp)
|
|
310
|
-
|
|
311
|
-
config.headers['Authorization'] = sign
|
|
312
|
-
return fetch(this.url, config, this.proxy)
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
getRequestSign(timestamp: number) {
|
|
316
|
-
const { method, url, service } = this
|
|
317
|
-
const { secretId, secretKey } = this.credential
|
|
318
|
-
const urlObj = new URL(url)
|
|
319
|
-
|
|
320
|
-
// 通用头部
|
|
321
|
-
let headers = ''
|
|
322
|
-
const signedHeaders = 'content-type;host'
|
|
323
|
-
if (method === 'GET') {
|
|
324
|
-
headers = 'content-type:application/x-www-form-urlencoded\n'
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (method === 'POST') {
|
|
328
|
-
headers = 'content-type:application/json\n'
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
let path = urlObj.pathname
|
|
332
|
-
if (path === '/api/v1/cliapi' && service === 'lowcode') {
|
|
333
|
-
path = '//lcap.cloud.tencent.com/api/v1/cliapi'
|
|
334
|
-
headers += 'host:lcap.cloud.tencent.com\n'
|
|
335
|
-
} else {
|
|
336
|
-
headers += `host:${this.host}\n`
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const querystring = urlObj.search.slice(1)
|
|
341
|
-
|
|
342
|
-
const payloadHash = this.payload ? getHash(JSON.stringify(this.payload)) : getHash('')
|
|
343
|
-
|
|
344
|
-
const canonicalRequest = `${method}\n${path}\n${querystring}\n${headers}\n${signedHeaders}\n${payloadHash}`
|
|
345
|
-
|
|
346
|
-
const date = getDate(timestamp)
|
|
347
|
-
|
|
348
|
-
const StringToSign = `TC3-HMAC-SHA256\n${timestamp}\n${date}/${service}/tc3_request\n${getHash(
|
|
349
|
-
canonicalRequest
|
|
350
|
-
)}`
|
|
351
|
-
|
|
352
|
-
const kDate = sha256(date, `TC3${secretKey}`)
|
|
353
|
-
const kService = sha256(service, kDate)
|
|
354
|
-
const kSigning = sha256('tc3_request', kService)
|
|
355
|
-
const signature = sha256(StringToSign, kSigning, 'hex')
|
|
356
|
-
|
|
357
|
-
return `TC3-HMAC-SHA256 Credential=${secretId}/${date}/${service}/tc3_request, SignedHeaders=${signedHeaders}, Signature=${signature}`
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
clearCredentialCache() {
|
|
361
|
-
this.credential = null
|
|
362
|
-
}
|
|
363
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
interface Options {
|
|
2
|
-
exit?: number;
|
|
3
|
-
original?: Error | undefined;
|
|
4
|
-
code?: string | number;
|
|
5
|
-
requestId?: string;
|
|
6
|
-
action?: string;
|
|
7
|
-
type?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class CloudBaseError extends Error {
|
|
11
|
-
readonly exit: number;
|
|
12
|
-
readonly message: string;
|
|
13
|
-
readonly name = 'CloudBaseError';
|
|
14
|
-
readonly original: Error | undefined;
|
|
15
|
-
readonly code: string | number;
|
|
16
|
-
readonly requestId: string;
|
|
17
|
-
readonly action: string;
|
|
18
|
-
readonly type: string;
|
|
19
|
-
|
|
20
|
-
constructor(message: string, options: Options = {}) {
|
|
21
|
-
super()
|
|
22
|
-
const { code = '', action = '', original = null, requestId = '', type } = options
|
|
23
|
-
this.message = `[${action}]\nRequestId:${requestId}\n${message}`
|
|
24
|
-
this.original = original
|
|
25
|
-
this.code = code
|
|
26
|
-
this.requestId = requestId
|
|
27
|
-
this.action = action
|
|
28
|
-
this.type = type
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './cloud-api-service'
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { URL } from 'url'
|
|
2
|
-
import _fetch, { RequestInit } from 'node-fetch'
|
|
3
|
-
import { HttpsProxyAgent } from 'https-proxy-agent'
|
|
4
|
-
|
|
5
|
-
export const nodeFetch = _fetch
|
|
6
|
-
|
|
7
|
-
// 使用 fetch + 代理
|
|
8
|
-
export async function fetch(url: string, config: RequestInit = {}, proxy = '') {
|
|
9
|
-
if (proxy) {
|
|
10
|
-
config.agent = new HttpsProxyAgent(proxy)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// 解决中文编码问题
|
|
14
|
-
const escapeUrl = new URL(url).toString()
|
|
15
|
-
|
|
16
|
-
const res = await _fetch(escapeUrl, config)
|
|
17
|
-
return res.json()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function fetchStream(url: string, config: RequestInit = {}, proxy = '') {
|
|
21
|
-
if (proxy) {
|
|
22
|
-
config.agent = new HttpsProxyAgent(proxy)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const escapeUrl = new URL(url).toString()
|
|
26
|
-
|
|
27
|
-
return _fetch(escapeUrl, config)
|
|
28
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { getCredentialWithoutCheck, getRegion, Credential, getProxy } from '@cloudbase/toolbox'
|
|
2
|
-
import { CloudApiService as _CloudApiService } from './tcbr-cloud-api/index'
|
|
3
|
-
import { CloudBaseError } from '../../error'
|
|
4
|
-
import { REQUEST_TIMEOUT } from '../../constant'
|
|
5
|
-
|
|
6
|
-
let commonCredential: Credential
|
|
7
|
-
|
|
8
|
-
// token 将在 n 分钟内过期
|
|
9
|
-
const isTokenExpired = (credential: Credential, gap = 120) =>
|
|
10
|
-
credential.accessTokenExpired && Number(credential.accessTokenExpired) < Date.now() + gap * 1000
|
|
11
|
-
|
|
12
|
-
export class CloudApiService {
|
|
13
|
-
// 缓存请求实例
|
|
14
|
-
static serviceCacheMap: Record<string, CloudApiService> = {}
|
|
15
|
-
|
|
16
|
-
// 单例模式
|
|
17
|
-
static getInstance(service: string) {
|
|
18
|
-
if (CloudApiService.serviceCacheMap?.[service]) {
|
|
19
|
-
return CloudApiService.serviceCacheMap[service]
|
|
20
|
-
}
|
|
21
|
-
const apiService = new CloudApiService(service)
|
|
22
|
-
CloudApiService.serviceCacheMap[service] = apiService
|
|
23
|
-
return apiService
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
region: string
|
|
27
|
-
apiService: _CloudApiService
|
|
28
|
-
|
|
29
|
-
constructor(service: string, baseParams?: Record<string, any>, version = '') {
|
|
30
|
-
// 初始化 API 实例
|
|
31
|
-
this.apiService = new _CloudApiService({
|
|
32
|
-
service,
|
|
33
|
-
version: service === 'tcr'
|
|
34
|
-
? version
|
|
35
|
-
: service === 'tcbr'
|
|
36
|
-
? '2022-02-17'
|
|
37
|
-
:'2019-09-24',
|
|
38
|
-
baseParams,
|
|
39
|
-
proxy: getProxy(),
|
|
40
|
-
timeout: REQUEST_TIMEOUT,
|
|
41
|
-
getCredential: async () => {
|
|
42
|
-
// 存在未过期的 token
|
|
43
|
-
if (commonCredential?.secretId && !isTokenExpired(commonCredential)) {
|
|
44
|
-
return commonCredential
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const credential = await getCredentialWithoutCheck()
|
|
48
|
-
if (!credential) {
|
|
49
|
-
throw new CloudBaseError('无有效身份信息,请使用 cloudbase login 登录')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
commonCredential = credential
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
...credential,
|
|
56
|
-
tokenExpired: Number(credential.accessTokenExpired)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async request(action: string, data: Record<string, any> = {}, method: 'POST' | 'GET' = 'POST') {
|
|
63
|
-
const region = this.region || (await getRegion())
|
|
64
|
-
return this.apiService.request({ action, data, method, region })
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { fetch as _fetch, fetchStream as _fetchStream } from './request';
|
|
2
|
-
export interface ServiceOptions {
|
|
3
|
-
service: string;
|
|
4
|
-
version?: string;
|
|
5
|
-
proxy?: string;
|
|
6
|
-
timeout?: number;
|
|
7
|
-
region?: string;
|
|
8
|
-
baseParams?: Record<string, any>;
|
|
9
|
-
credential?: Credential;
|
|
10
|
-
getCredential?: () => Promise<Credential> | Credential;
|
|
11
|
-
}
|
|
12
|
-
export interface Credential {
|
|
13
|
-
secretId: string;
|
|
14
|
-
secretKey: string;
|
|
15
|
-
token?: string;
|
|
16
|
-
tokenExpired?: number;
|
|
17
|
-
}
|
|
18
|
-
export interface RequestOptions {
|
|
19
|
-
action: string;
|
|
20
|
-
data?: Record<string, any>;
|
|
21
|
-
method?: 'POST' | 'GET';
|
|
22
|
-
region?: string;
|
|
23
|
-
}
|
|
24
|
-
export declare const fetch: typeof _fetch;
|
|
25
|
-
export declare const fetchStream: typeof _fetchStream;
|
|
26
|
-
export declare const nodeFetch: typeof import("node-fetch").default;
|
|
27
|
-
export declare class CloudApiService {
|
|
28
|
-
static serviceCacheMap: Record<string, CloudApiService>;
|
|
29
|
-
static getInstance(options: ServiceOptions): CloudApiService;
|
|
30
|
-
service: string;
|
|
31
|
-
version: string;
|
|
32
|
-
proxy: string;
|
|
33
|
-
timeout: number;
|
|
34
|
-
region: string;
|
|
35
|
-
credential: Credential;
|
|
36
|
-
baseParams: Record<string, any>;
|
|
37
|
-
getCredential: () => Promise<Credential> | Credential;
|
|
38
|
-
url: string;
|
|
39
|
-
host: string;
|
|
40
|
-
action: string;
|
|
41
|
-
method: 'POST' | 'GET';
|
|
42
|
-
data: Record<string, any>;
|
|
43
|
-
payload: Record<string, any>;
|
|
44
|
-
constructor(options: ServiceOptions);
|
|
45
|
-
get baseUrl(): any;
|
|
46
|
-
request(options: RequestOptions): any;
|
|
47
|
-
request(action: string, data?: Record<string, any>, method?: 'POST' | 'GET'): any;
|
|
48
|
-
requestWithSign(region: any): Promise<any>;
|
|
49
|
-
getRequestSign(timestamp: number): string;
|
|
50
|
-
clearCredentialCache(): void;
|
|
51
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
interface Options {
|
|
2
|
-
exit?: number;
|
|
3
|
-
original?: Error | undefined;
|
|
4
|
-
code?: string | number;
|
|
5
|
-
requestId?: string;
|
|
6
|
-
action?: string;
|
|
7
|
-
type?: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class CloudBaseError extends Error {
|
|
10
|
-
readonly exit: number;
|
|
11
|
-
readonly message: string;
|
|
12
|
-
readonly name = "CloudBaseError";
|
|
13
|
-
readonly original: Error | undefined;
|
|
14
|
-
readonly code: string | number;
|
|
15
|
-
readonly requestId: string;
|
|
16
|
-
readonly action: string;
|
|
17
|
-
readonly type: string;
|
|
18
|
-
constructor(message: string, options?: Options);
|
|
19
|
-
}
|
|
20
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './cloud-api-service';
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import _fetch, { RequestInit } from 'node-fetch';
|
|
2
|
-
export declare const nodeFetch: typeof _fetch;
|
|
3
|
-
export declare function fetch(url: string, config?: RequestInit, proxy?: string): Promise<any>;
|
|
4
|
-
export declare function fetchStream(url: string, config?: RequestInit, proxy?: string): Promise<import("node-fetch").Response>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { CloudApiService as _CloudApiService } from './tcbr-cloud-api/index';
|
|
2
|
-
export declare class CloudApiService {
|
|
3
|
-
static serviceCacheMap: Record<string, CloudApiService>;
|
|
4
|
-
static getInstance(service: string): CloudApiService;
|
|
5
|
-
region: string;
|
|
6
|
-
apiService: _CloudApiService;
|
|
7
|
-
constructor(service: string, baseParams?: Record<string, any>, version?: string);
|
|
8
|
-
request(action: string, data?: Record<string, any>, method?: 'POST' | 'GET'): Promise<any>;
|
|
9
|
-
}
|