huaweicloud-devkit 1.0.2-dev.8 → 1.0.2-next.0
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/.agents/plugins/marketplace.json +20 -20
- package/LICENSE +201 -201
- package/README.md +163 -138
- package/README.zh-CN.md +161 -138
- package/bin/setup.cjs +8 -8
- package/integrations/opencode/commands/huaweicloud-doctor.md +14 -14
- package/integrations/opencode/opencode.json +14 -14
- package/integrations/opencode/skills/huaweicloud-core/SKILL.md +32 -32
- package/package.json +46 -44
- package/plugins/huaweicloud-core/.claude-plugin/plugin.json +44 -44
- package/plugins/huaweicloud-core/.codex-plugin/plugin.json +43 -43
- package/plugins/huaweicloud-core/.cursor-plugin/plugin.json +44 -44
- package/plugins/huaweicloud-core/.mcp.json +15 -15
- package/plugins/huaweicloud-core/.workbuddy-plugin/plugin.json +44 -44
- package/plugins/huaweicloud-core/hooks/hooks.json +26 -26
- package/plugins/huaweicloud-core/hooks/huaweicloud-safety.py +136 -136
- package/plugins/huaweicloud-core/safety/policy.json +99 -100
- package/plugins/huaweicloud-core/safety/rules/cloud-risk-rules.json +199 -199
- package/plugins/huaweicloud-core/skills/huawei-apig/SKILL.md +164 -164
- package/plugins/huaweicloud-core/skills/huawei-billing/SKILL.md +48 -48
- package/plugins/huaweicloud-core/skills/huawei-cbr/SKILL.md +50 -50
- package/plugins/huaweicloud-core/skills/huawei-cce/SKILL.md +101 -101
- package/plugins/huaweicloud-core/skills/huawei-cloud-eye/SKILL.md +90 -90
- package/plugins/huaweicloud-core/skills/huawei-cloud-find-skills/SKILL.md +190 -190
- package/plugins/huaweicloud-core/skills/huawei-cloud-find-skills/scripts/search-skills.mjs +124 -124
- package/plugins/huaweicloud-core/skills/huawei-cts/SKILL.md +55 -55
- package/plugins/huaweicloud-core/skills/huawei-dds-dcs/SKILL.md +70 -70
- package/plugins/huaweicloud-core/skills/huawei-deployment/SKILL.md +56 -56
- package/plugins/huaweicloud-core/skills/huawei-dew/SKILL.md +97 -97
- package/plugins/huaweicloud-core/skills/huawei-dew/references/csms-usage.md +29 -29
- package/plugins/huaweicloud-core/skills/huawei-dew/references/kms-usage.md +23 -23
- package/plugins/huaweicloud-core/skills/huawei-ecs/SKILL.md +185 -185
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/create-instance.md +133 -133
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/evs.md +31 -31
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/flavors.md +55 -55
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/troubleshooting.md +52 -52
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/SKILL.md +131 -131
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/apig-event-format.md +58 -58
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/create-function.md +71 -71
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/deploy-workflow.md +119 -119
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/triggers.md +142 -142
- package/plugins/huaweicloud-core/skills/huawei-gaussdb/SKILL.md +56 -56
- package/plugins/huaweicloud-core/skills/huawei-getting-started/SKILL.md +65 -65
- package/plugins/huaweicloud-core/skills/huawei-iam/SKILL.md +111 -111
- package/plugins/huaweicloud-core/skills/huawei-iam/references/policy-examples.md +122 -122
- package/plugins/huaweicloud-core/skills/huawei-iam/references/quick-ref.md +56 -56
- package/plugins/huaweicloud-core/skills/huawei-modelarts/SKILL.md +65 -65
- package/plugins/huaweicloud-core/skills/huawei-obs/SKILL.md +133 -127
- package/plugins/huaweicloud-core/skills/huawei-obs/references/bucket-create.md +49 -49
- package/plugins/huaweicloud-core/skills/huawei-obs/references/bucket-lifecycle.md +26 -26
- package/plugins/huaweicloud-core/skills/huawei-obs/references/common-pitfalls.md +100 -100
- package/plugins/huaweicloud-core/skills/huawei-obs/references/single-file-share.md +40 -40
- package/plugins/huaweicloud-core/skills/huawei-obs/references/static-website.md +56 -56
- package/plugins/huaweicloud-core/skills/huawei-rds/SKILL.md +224 -224
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +135 -131
- package/plugins/huaweicloud-core/skills/huawei-smn-dms/SKILL.md +69 -69
- package/plugins/huaweicloud-core/skills/huawei-vpc/SKILL.md +84 -84
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/network.md +76 -76
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/security-group.md +59 -59
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/subnet.md +50 -50
- package/plugins/huaweicloud-core/skills/huawei-waf-aad/SKILL.md +63 -63
- package/plugins/huaweicloud-core/skills/huaweicloud-api-and-sdk/SKILL.md +56 -56
- package/plugins/huaweicloud-core/skills/huaweicloud-api-and-sdk/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/SKILL.md +51 -47
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/SKILL.md +128 -127
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +110 -95
- package/plugins/huaweicloud-core/skills/huaweicloud-core/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-core/references/report-issue.md +19 -19
- package/plugins/huaweicloud-core/skills/huaweicloud-core/references/select.md +27 -27
- package/plugins/huaweicloud-core/skills/huaweicloud-safety/SKILL.md +60 -60
- package/plugins/huaweicloud-core/skills/huaweicloud-safety/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/skills/huaweicloud-troubleshooting/SKILL.md +83 -83
- package/plugins/huaweicloud-core/skills/huaweicloud-troubleshooting/agents/openai.yaml +4 -4
- package/plugins/huaweicloud-core/src/auth/agent-registration.mjs +105 -87
- package/plugins/huaweicloud-core/src/auth/credentials.mjs +95 -95
- package/plugins/huaweicloud-core/src/auth/service.mjs +63 -63
- package/plugins/huaweicloud-core/src/hcloud-cli.mjs +265 -265
- package/plugins/huaweicloud-core/src/mcp-server.mjs +129 -129
- package/plugins/huaweicloud-core/src/proxy/proxy-agent.mjs +155 -0
- package/plugins/huaweicloud-core/src/proxy/proxy-config.mjs +87 -0
- package/plugins/huaweicloud-core/src/risk-rule-engine.mjs +137 -137
- package/plugins/huaweicloud-core/src/safety-policy.mjs +302 -302
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +91 -97
- package/plugins/huaweicloud-core/src/sandbox/hwlink-api.mjs +162 -153
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +112 -105
- package/plugins/huaweicloud-core/src/search-market.mjs +174 -169
- package/plugins/huaweicloud-core/src/setup-cli.mjs +2017 -1576
- package/plugins/huaweicloud-core/src/tools.mjs +1008 -1005
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-exec-client.js +427 -427
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-fair-queue.js +132 -132
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-multiplexer.js +227 -227
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-packet.js +202 -202
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-terminal-channel.js +158 -158
- package/plugins/huaweicloud-core/src/ws-exec/index.js +19 -19
- package/plugins/huaweicloud-core/src/ws-exec/ws-exec-client.js +338 -338
|
@@ -1,97 +1,91 @@
|
|
|
1
|
-
import { getCredentials } from './hwlink-api.mjs';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'
|
|
13
|
-
'X-HW-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
err
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function
|
|
61
|
-
return await hdkitRequest('
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (options.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!sessionId && !devStageId) {
|
|
93
|
-
throw new Error('session_id or dev_stage_id is required');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return await hdkitRequest('POST', 'release', body);
|
|
97
|
-
}
|
|
1
|
+
import { getCredentials } from './hwlink-api.mjs';
|
|
2
|
+
import { getProxyDispatcher } from '../proxy/proxy-agent.mjs';
|
|
3
|
+
|
|
4
|
+
const HDKIT_BASE_URL =
|
|
5
|
+
process.env.HDKITSERVICE_ENDPOINT ||
|
|
6
|
+
'https://devkit.huaweicloud.com/rest/developer/server/hdkitservice/';
|
|
7
|
+
|
|
8
|
+
async function hdkitRequest(method, path, body, timeoutMs = 300000) {
|
|
9
|
+
const { ak, sk, securitytoken } = getCredentials();
|
|
10
|
+
|
|
11
|
+
const headers = {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
'X-HW-AK': ak,
|
|
14
|
+
'X-HW-SK': sk,
|
|
15
|
+
};
|
|
16
|
+
if (securitytoken) {
|
|
17
|
+
headers['X-HW-Security-Token'] = securitytoken;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const url = `${HDKIT_BASE_URL}${path}`;
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
23
|
+
|
|
24
|
+
let resp;
|
|
25
|
+
try {
|
|
26
|
+
const dispatcher = await getProxyDispatcher(url);
|
|
27
|
+
const fetchOpts = {
|
|
28
|
+
method,
|
|
29
|
+
headers,
|
|
30
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
31
|
+
signal: controller.signal,
|
|
32
|
+
};
|
|
33
|
+
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
34
|
+
resp = await fetch(url, fetchOpts);
|
|
35
|
+
} finally {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const text = await resp.text();
|
|
40
|
+
let data;
|
|
41
|
+
try {
|
|
42
|
+
data = JSON.parse(text);
|
|
43
|
+
} catch {
|
|
44
|
+
throw new Error(`hdkitservice returned non-JSON (status ${resp.status}): ${text.slice(0, 200)}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!resp.ok) {
|
|
48
|
+
const err = new Error(
|
|
49
|
+
data.message || `hdkitservice error: ${data.code || resp.status}`
|
|
50
|
+
);
|
|
51
|
+
err.code = data.code;
|
|
52
|
+
err.status = resp.status;
|
|
53
|
+
err.traceId = data.traceId; // 后端实际返回驼峰 traceId
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return data;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function hdkitCheckUser() {
|
|
61
|
+
return await hdkitRequest('GET', 'check-user', undefined, 30000);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function hdkitSignAgreement() {
|
|
65
|
+
return await hdkitRequest('POST', 'sign-agreement', {});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function hdkitConnect(options = {}) {
|
|
69
|
+
const body = {};
|
|
70
|
+
if (options.source) body.source = options.source;
|
|
71
|
+
if (options.env) body.env = options.env;
|
|
72
|
+
if (options.git) body.git = options.git;
|
|
73
|
+
if (options.template_id) body.template_id = options.template_id;
|
|
74
|
+
if (options.flavor_id) body.flavor_id = options.flavor_id;
|
|
75
|
+
|
|
76
|
+
return await hdkitRequest('POST', 'connect', body);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function hdkitCredentials(sessionId, devStageId, enableSts = true) {
|
|
80
|
+
const body = { enable_sts: enableSts };
|
|
81
|
+
if (sessionId) body.session_id = sessionId;
|
|
82
|
+
if (devStageId) body.dev_stage_id = devStageId;
|
|
83
|
+
|
|
84
|
+
if (!sessionId && !devStageId) {
|
|
85
|
+
throw new Error('session_id or dev_stage_id is required');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return await hdkitRequest('POST', 'credentials', body);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
@@ -1,153 +1,162 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import { resolveCredentials } from '../auth/credentials.mjs';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.
|
|
35
|
-
.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
.
|
|
53
|
-
.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import { resolveCredentials } from '../auth/credentials.mjs';
|
|
3
|
+
import { getProxyDispatcher } from '../proxy/proxy-agent.mjs';
|
|
4
|
+
|
|
5
|
+
const BASE_URL = process.env.HWLINK_ENDPOINT || 'https://devstation.myhuaweicloud.com';
|
|
6
|
+
|
|
7
|
+
function sha256Hex(data) {
|
|
8
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function hmacSha256(key, data) {
|
|
12
|
+
return crypto.createHmac('sha256', key).update(data).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function urlEncode(str) {
|
|
16
|
+
const hex = (c) => '%' + (c < 16 ? '0' : '') + c.toString(16).toUpperCase();
|
|
17
|
+
const noEscape = new Set(
|
|
18
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~'.split('')
|
|
19
|
+
);
|
|
20
|
+
let out = '';
|
|
21
|
+
for (const ch of str) {
|
|
22
|
+
const c = ch.codePointAt(0);
|
|
23
|
+
out += noEscape.has(ch) && c < 0x80 ? ch : c < 0x80 ? hex(c) : encodeURIComponent(ch);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function timestamp() {
|
|
29
|
+
return new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, '') + 'Z';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function sortedQs(query) {
|
|
33
|
+
return Object.entries(query)
|
|
34
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
35
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
36
|
+
.join('&');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function signRequest(method, path, query, body, ak, sk, securitytoken) {
|
|
40
|
+
const ts = timestamp();
|
|
41
|
+
const host = new URL(BASE_URL).host;
|
|
42
|
+
|
|
43
|
+
const cqs = Object.entries(query)
|
|
44
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
45
|
+
.map(([k, v]) => `${urlEncode(k)}=${urlEncode(v)}`)
|
|
46
|
+
.join('&');
|
|
47
|
+
|
|
48
|
+
const curi =
|
|
49
|
+
'/' +
|
|
50
|
+
path
|
|
51
|
+
.split('/')
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.map((s) => urlEncode(s))
|
|
54
|
+
.join('/') +
|
|
55
|
+
'/';
|
|
56
|
+
|
|
57
|
+
const signedHeaders = securitytoken
|
|
58
|
+
? 'host;x-sdk-date;x-security-token'
|
|
59
|
+
: 'host;x-sdk-date';
|
|
60
|
+
const canonicalHeaders = securitytoken
|
|
61
|
+
? `host:${host}\nx-sdk-date:${ts}\nx-security-token:${securitytoken}\n`
|
|
62
|
+
: `host:${host}\nx-sdk-date:${ts}\n`;
|
|
63
|
+
|
|
64
|
+
const bodyStr = body ? JSON.stringify(body) : '';
|
|
65
|
+
const payloadHash = sha256Hex(bodyStr);
|
|
66
|
+
|
|
67
|
+
const canonicalRequest = [
|
|
68
|
+
method,
|
|
69
|
+
curi,
|
|
70
|
+
cqs,
|
|
71
|
+
canonicalHeaders,
|
|
72
|
+
signedHeaders,
|
|
73
|
+
payloadHash,
|
|
74
|
+
].join('\n');
|
|
75
|
+
|
|
76
|
+
const stringToSign = `SDK-HMAC-SHA256\n${ts}\n${sha256Hex(canonicalRequest)}`;
|
|
77
|
+
const signature = hmacSha256(sk, stringToSign);
|
|
78
|
+
|
|
79
|
+
const headers = {
|
|
80
|
+
host,
|
|
81
|
+
'x-sdk-date': ts,
|
|
82
|
+
Authorization: `SDK-HMAC-SHA256 Access=${ak}, SignedHeaders=${signedHeaders}, Signature=${signature}`,
|
|
83
|
+
};
|
|
84
|
+
if (securitytoken) {
|
|
85
|
+
headers['x-security-token'] = securitytoken;
|
|
86
|
+
}
|
|
87
|
+
return headers;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function getCredentials() {
|
|
91
|
+
const credentials = resolveCredentials();
|
|
92
|
+
return { ak: credentials.ak, sk: credentials.sk, securitytoken: credentials.securityToken };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function apiGet(path, query, ak, sk, securitytoken) {
|
|
96
|
+
query = query || {};
|
|
97
|
+
const qs = sortedQs(query);
|
|
98
|
+
const fullPath = qs ? `${path}?${qs}` : path;
|
|
99
|
+
const headers = signRequest('GET', path, query, undefined, ak, sk, securitytoken);
|
|
100
|
+
const url = `${BASE_URL}${fullPath}`;
|
|
101
|
+
const dispatcher = await getProxyDispatcher(url);
|
|
102
|
+
const fetchOpts = { headers };
|
|
103
|
+
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
104
|
+
const resp = await fetch(url, fetchOpts);
|
|
105
|
+
return { status: resp.status, data: await resp.json() };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function apiPost(path, body, ak, sk, securitytoken) {
|
|
109
|
+
const headers = signRequest('POST', path, {}, body, ak, sk, securitytoken);
|
|
110
|
+
const url = `${BASE_URL}${path}`;
|
|
111
|
+
const dispatcher = await getProxyDispatcher(url);
|
|
112
|
+
const fetchOpts = {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
115
|
+
body: JSON.stringify(body),
|
|
116
|
+
};
|
|
117
|
+
if (dispatcher) fetchOpts.dispatcher = dispatcher;
|
|
118
|
+
const resp = await fetch(url, fetchOpts);
|
|
119
|
+
return { status: resp.status, data: await resp.json() };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function createConnection(envId, ak, sk, securitytoken) {
|
|
123
|
+
const { status, data } = await apiPost(
|
|
124
|
+
`/open-api-public/v1/devenvs/${envId}/connections`,
|
|
125
|
+
{ source: 'CLI' },
|
|
126
|
+
ak, sk, securitytoken
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (status !== 200 || data?.error_code !== '0000' || !data?.result?.connection_id) {
|
|
130
|
+
throw new Error(`Failed to create connection: ${JSON.stringify(data)}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const connectionId = data.result.connection_id;
|
|
134
|
+
const maxAttempts = 60;
|
|
135
|
+
|
|
136
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
137
|
+
process.stderr.write(`\rWaiting for connection ${connectionId}... (${i}s)`);
|
|
138
|
+
const { data: getData } = await apiGet(
|
|
139
|
+
`/open-api-public/v1/devenvs/${envId}/connections/${connectionId}`,
|
|
140
|
+
{},
|
|
141
|
+
ak, sk, securitytoken
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
getData?.result?.connection_info?.url &&
|
|
146
|
+
getData.result.connection_info.extensions?.source != null
|
|
147
|
+
) {
|
|
148
|
+
const u = new URL(getData.result.connection_info.url);
|
|
149
|
+
u.searchParams.set('source', String(getData.result.connection_info.extensions.source));
|
|
150
|
+
process.stderr.write(`\rConnection ${connectionId} established (${i}s).\n`);
|
|
151
|
+
return {
|
|
152
|
+
wsUrl: u.toString(),
|
|
153
|
+
source: getData.result.connection_info.extensions.source,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
throw new Error(`Timed out waiting for connection ${connectionId}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|