@cloudbase/node-sdk 3.17.1 → 3.17.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/dist/ai/index.js +58 -0
- package/dist/ai/request-adapter.js +259 -0
- package/package.json +1 -1
package/dist/ai/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.createAI = void 0;
|
|
27
|
+
const ai_1 = require("@cloudbase/ai");
|
|
28
|
+
const request_adapter_1 = require("./request-adapter");
|
|
29
|
+
const tcbopenapiendpoint_1 = require("../utils/tcbopenapiendpoint");
|
|
30
|
+
const symbol_1 = require("../const/symbol");
|
|
31
|
+
const openapicommonrequester = __importStar(require("../utils/tcbopenapicommonrequester"));
|
|
32
|
+
const app_1 = require("@cloudbase/app");
|
|
33
|
+
/**
|
|
34
|
+
* 创建 AI 实例
|
|
35
|
+
* @param cloudbase CloudBase 实例
|
|
36
|
+
* @returns AI 实例
|
|
37
|
+
*/
|
|
38
|
+
function createAI(cloudbase) {
|
|
39
|
+
const config = cloudbase.config;
|
|
40
|
+
// 获取环境 ID
|
|
41
|
+
const envId = config.envName === symbol_1.SYMBOL_CURRENT_ENV ? openapicommonrequester.getEnvIdFromContext() : config.envName;
|
|
42
|
+
// 构建 AI 基础 URL
|
|
43
|
+
const baseUrl = (0, tcbopenapiendpoint_1.buildCommonOpenApiUrlWithPath)({
|
|
44
|
+
serviceUrl: config.serviceUrl,
|
|
45
|
+
envId,
|
|
46
|
+
path: '/v1',
|
|
47
|
+
region: config.region
|
|
48
|
+
});
|
|
49
|
+
// 创建请求适配器
|
|
50
|
+
const requestAdapter = new request_adapter_1.AIRequestAdapter(config, async () => {
|
|
51
|
+
const credential = await cloudbase.auth().getClientCredential();
|
|
52
|
+
return credential.access_token;
|
|
53
|
+
});
|
|
54
|
+
// 创建 AI 实例
|
|
55
|
+
const ai = new ai_1.AI(requestAdapter, baseUrl, { t: (s) => s, lang: app_1.LANGS.ZH, LANG_HEADER_KEY: 'Accept-Language' });
|
|
56
|
+
return ai;
|
|
57
|
+
}
|
|
58
|
+
exports.createAI = createAI;
|
|
@@ -0,0 +1,259 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.AIRequestAdapter = void 0;
|
|
27
|
+
const openapicommonrequester = __importStar(require("../utils/tcbopenapicommonrequester"));
|
|
28
|
+
const web_streams_polyfill_1 = require("web-streams-polyfill");
|
|
29
|
+
const utils_1 = require("../utils/utils");
|
|
30
|
+
class AIRequestAdapter {
|
|
31
|
+
constructor(config, getAccessToken) {
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.getAccessToken = getAccessToken;
|
|
34
|
+
}
|
|
35
|
+
async fetch(options) {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const { url, stream = false, timeout, method = 'POST', headers, body } = options;
|
|
38
|
+
const headersObj = {};
|
|
39
|
+
if (isHeaders(headers)) {
|
|
40
|
+
headers.forEach((value, key) => {
|
|
41
|
+
headersObj[key] = value;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else if (Array.isArray(headers)) {
|
|
45
|
+
headers.forEach(([k, v]) => (headersObj[k] = v));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
Object.assign(headersObj, headers);
|
|
49
|
+
}
|
|
50
|
+
let parsedBody;
|
|
51
|
+
if (typeof body === 'string') {
|
|
52
|
+
try {
|
|
53
|
+
parsedBody = JSON.parse(body);
|
|
54
|
+
}
|
|
55
|
+
catch (_c) {
|
|
56
|
+
parsedBody = body;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
parsedBody = body;
|
|
61
|
+
}
|
|
62
|
+
const token = await this.getAccessToken();
|
|
63
|
+
const result = await openapicommonrequester.request({
|
|
64
|
+
config: this.config,
|
|
65
|
+
data: parsedBody,
|
|
66
|
+
method: (method === null || method === void 0 ? void 0 : method.toUpperCase()) || 'POST',
|
|
67
|
+
url,
|
|
68
|
+
headers: Object.assign({ 'Content-Type': 'application/json' }, headersObj),
|
|
69
|
+
token,
|
|
70
|
+
opts: {
|
|
71
|
+
timeout: timeout || this.config.timeout,
|
|
72
|
+
stream
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const { body: bodyData, headers: responseHeaders, statusCode } = result;
|
|
76
|
+
if (statusCode < 200 || statusCode >= 300) {
|
|
77
|
+
let errorMessage = `Request failed with status code ${statusCode}`;
|
|
78
|
+
let errorCode = `${statusCode}`;
|
|
79
|
+
let requestId = '';
|
|
80
|
+
let errorBody = null;
|
|
81
|
+
if (typeof bodyData === 'string') {
|
|
82
|
+
errorBody = bodyData;
|
|
83
|
+
}
|
|
84
|
+
else if (Buffer.isBuffer(bodyData)) {
|
|
85
|
+
errorBody = bodyData.toString('utf-8');
|
|
86
|
+
}
|
|
87
|
+
else if (bodyData && typeof bodyData === 'object' && typeof bodyData.on === 'function') {
|
|
88
|
+
errorBody = await readStreamToString(bodyData);
|
|
89
|
+
}
|
|
90
|
+
if (errorBody) {
|
|
91
|
+
try {
|
|
92
|
+
const errorData = JSON.parse(errorBody);
|
|
93
|
+
if ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.message) {
|
|
94
|
+
errorMessage = errorData.error.message;
|
|
95
|
+
}
|
|
96
|
+
else if (errorData.message) {
|
|
97
|
+
errorMessage = errorData.message;
|
|
98
|
+
}
|
|
99
|
+
if ((_b = errorData.error) === null || _b === void 0 ? void 0 : _b.code) {
|
|
100
|
+
errorCode = errorData.error.code;
|
|
101
|
+
}
|
|
102
|
+
else if (errorData.code) {
|
|
103
|
+
errorCode = errorData.code;
|
|
104
|
+
}
|
|
105
|
+
if (errorData.requestId) {
|
|
106
|
+
requestId = errorData.requestId;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (_d) {
|
|
110
|
+
errorMessage = errorBody || errorMessage;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// 从响应头中获取 requestId
|
|
114
|
+
if (!requestId && responseHeaders) {
|
|
115
|
+
const headerRequestId = responseHeaders['x-cloudbase-request-id'] || responseHeaders['x-request-id'] || '';
|
|
116
|
+
requestId = Array.isArray(headerRequestId) ? headerRequestId[0] : headerRequestId;
|
|
117
|
+
}
|
|
118
|
+
throw (0, utils_1.E)({
|
|
119
|
+
code: errorCode,
|
|
120
|
+
message: errorMessage,
|
|
121
|
+
requestId
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (stream) {
|
|
125
|
+
// 对于流式响应,将 Node.js 原生流转换为 Web ReadableStream
|
|
126
|
+
let readableStream;
|
|
127
|
+
if (bodyData && typeof bodyData === 'object' && 'on' in bodyData && typeof bodyData.on === 'function') {
|
|
128
|
+
const nodeStream = bodyData;
|
|
129
|
+
// Node 12 兼容: 使用标志位追踪 stream 状态,避免重复 close 导致异常
|
|
130
|
+
let streamClosed = false;
|
|
131
|
+
readableStream = new web_streams_polyfill_1.ReadableStream({
|
|
132
|
+
start(controller) {
|
|
133
|
+
nodeStream.on('data', (chunk) => {
|
|
134
|
+
if (streamClosed)
|
|
135
|
+
return;
|
|
136
|
+
controller.enqueue(new Uint8Array(chunk));
|
|
137
|
+
});
|
|
138
|
+
nodeStream.on('end', () => {
|
|
139
|
+
if (streamClosed)
|
|
140
|
+
return;
|
|
141
|
+
streamClosed = true;
|
|
142
|
+
controller.close();
|
|
143
|
+
});
|
|
144
|
+
nodeStream.on('error', (err) => {
|
|
145
|
+
if (streamClosed)
|
|
146
|
+
return;
|
|
147
|
+
streamClosed = true;
|
|
148
|
+
controller.error(err);
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
cancel() {
|
|
152
|
+
streamClosed = true;
|
|
153
|
+
nodeStream.destroy();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else if (bodyData instanceof Buffer) {
|
|
158
|
+
readableStream = new web_streams_polyfill_1.ReadableStream({
|
|
159
|
+
start(controller) {
|
|
160
|
+
controller.enqueue(new Uint8Array(bodyData));
|
|
161
|
+
controller.close();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else if (typeof bodyData === 'string') {
|
|
166
|
+
const encoder = new TextEncoder();
|
|
167
|
+
readableStream = new web_streams_polyfill_1.ReadableStream({
|
|
168
|
+
start(controller) {
|
|
169
|
+
controller.enqueue(encoder.encode(bodyData));
|
|
170
|
+
controller.close();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
readableStream = new web_streams_polyfill_1.ReadableStream({
|
|
176
|
+
start(controller) {
|
|
177
|
+
controller.close();
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
data: readableStream,
|
|
183
|
+
statusCode,
|
|
184
|
+
header: responseHeaders
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
let responseData;
|
|
188
|
+
if (typeof bodyData === 'string') {
|
|
189
|
+
try {
|
|
190
|
+
responseData = JSON.parse(bodyData);
|
|
191
|
+
}
|
|
192
|
+
catch (_e) {
|
|
193
|
+
responseData = bodyData;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else if (bodyData instanceof Buffer) {
|
|
197
|
+
const bodyString = bodyData.toString('utf-8');
|
|
198
|
+
try {
|
|
199
|
+
responseData = JSON.parse(bodyString);
|
|
200
|
+
}
|
|
201
|
+
catch (_f) {
|
|
202
|
+
responseData = bodyString;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
responseData = bodyData;
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
data: Promise.resolve(responseData),
|
|
210
|
+
statusCode,
|
|
211
|
+
header: responseHeaders
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* post 方法 - AI 模块可能不使用,但需要实现接口
|
|
216
|
+
*/
|
|
217
|
+
async post() {
|
|
218
|
+
throw new Error('post method is not supported in AI module');
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* upload 方法 - AI 模块可能不使用,但需要实现接口
|
|
222
|
+
*/
|
|
223
|
+
async upload() {
|
|
224
|
+
throw new Error('upload method is not supported in AI module');
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* download 方法 - AI 模块可能不使用,但需要实现接口
|
|
228
|
+
*/
|
|
229
|
+
async download() {
|
|
230
|
+
throw new Error('download method is not supported in AI module');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.AIRequestAdapter = AIRequestAdapter;
|
|
234
|
+
function isHeaders(h) {
|
|
235
|
+
try {
|
|
236
|
+
// Node.js 低版本可能没有 Headers
|
|
237
|
+
return h instanceof Headers;
|
|
238
|
+
}
|
|
239
|
+
catch (_) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 从 Node.js 流中读取完整内容为字符串
|
|
245
|
+
*/
|
|
246
|
+
async function readStreamToString(stream) {
|
|
247
|
+
return await new Promise((resolve, reject) => {
|
|
248
|
+
const chunks = [];
|
|
249
|
+
stream.on('data', (chunk) => {
|
|
250
|
+
chunks.push(chunk);
|
|
251
|
+
});
|
|
252
|
+
stream.on('end', () => {
|
|
253
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
254
|
+
});
|
|
255
|
+
stream.on('error', (err) => {
|
|
256
|
+
reject(err);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
}
|