agc-api-cli 1.0.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/dist/index.js ADDED
@@ -0,0 +1,455 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ AuthService: () => AuthService,
34
+ ProvisionService: () => ProvisionService,
35
+ PublishService: () => PublishService,
36
+ UploadService: () => UploadService,
37
+ agcClient: () => agcClient,
38
+ getConfig: () => getConfig
39
+ });
40
+ module.exports = __toCommonJS(src_exports);
41
+
42
+ // src/services/auth.ts
43
+ var import_axios = __toESM(require("axios"));
44
+
45
+ // src/config/index.ts
46
+ var dotenv = __toESM(require("dotenv"));
47
+ var import_path = __toESM(require("path"));
48
+ var import_fs = __toESM(require("fs"));
49
+ var envPath = import_path.default.resolve(process.cwd(), ".env");
50
+ if (import_fs.default.existsSync(envPath)) {
51
+ dotenv.config({ path: envPath });
52
+ } else {
53
+ dotenv.config();
54
+ }
55
+ function getConfig() {
56
+ const clientId = process.env.AGC_CLIENT_ID;
57
+ const clientSecret = process.env.AGC_CLIENT_SECRET;
58
+ if (!clientId || !clientSecret) {
59
+ throw new Error("Missing AGC credentials. Please set AGC_CLIENT_ID and AGC_CLIENT_SECRET environment variables.");
60
+ }
61
+ return {
62
+ clientId,
63
+ clientSecret,
64
+ domain: process.env.AGC_DOMAIN || "connect-api.cloud.huawei.com"
65
+ };
66
+ }
67
+
68
+ // src/services/auth.ts
69
+ var AuthService = class {
70
+ /**
71
+ * 获取访问API的Token
72
+ */
73
+ static async getToken() {
74
+ const config2 = getConfig();
75
+ const url = `https://${config2.domain}/api/oauth2/v1/token`;
76
+ const payload = {
77
+ grant_type: "client_credentials",
78
+ client_id: config2.clientId,
79
+ client_secret: config2.clientSecret
80
+ };
81
+ const response = await import_axios.default.post(url, payload, {
82
+ headers: {
83
+ "Content-Type": "application/json"
84
+ }
85
+ });
86
+ return response.data;
87
+ }
88
+ };
89
+
90
+ // src/core/http.ts
91
+ var import_axios2 = __toESM(require("axios"));
92
+
93
+ // src/core/auth-mgr.ts
94
+ var import_fs2 = __toESM(require("fs"));
95
+ var import_path2 = __toESM(require("path"));
96
+ var import_os = __toESM(require("os"));
97
+ var AuthManager = class {
98
+ static cacheFile = import_path2.default.join(import_os.default.homedir(), ".agc-cli-token.json");
99
+ static async getAccessToken() {
100
+ const cache = this.readCache();
101
+ if (cache && cache.expiresAt > Date.now() + 5 * 60 * 1e3) {
102
+ return cache.accessToken;
103
+ }
104
+ const res = await AuthService.getToken();
105
+ if (res.access_token && res.expires_in) {
106
+ const expiresAt = Date.now() + res.expires_in * 1e3;
107
+ this.writeCache({ accessToken: res.access_token, expiresAt });
108
+ return res.access_token;
109
+ }
110
+ throw new Error(`Failed to get token: ${JSON.stringify(res.ret)}`);
111
+ }
112
+ static readCache() {
113
+ try {
114
+ if (import_fs2.default.existsSync(this.cacheFile)) {
115
+ const data = import_fs2.default.readFileSync(this.cacheFile, "utf8");
116
+ return JSON.parse(data);
117
+ }
118
+ } catch (e) {
119
+ }
120
+ return null;
121
+ }
122
+ static writeCache(cache) {
123
+ try {
124
+ import_fs2.default.writeFileSync(this.cacheFile, JSON.stringify(cache, null, 2), "utf8");
125
+ } catch (e) {
126
+ }
127
+ }
128
+ /**
129
+ * 清除缓存的 Token(登出)
130
+ */
131
+ static clearCache() {
132
+ try {
133
+ if (import_fs2.default.existsSync(this.cacheFile)) {
134
+ import_fs2.default.unlinkSync(this.cacheFile);
135
+ return true;
136
+ }
137
+ return false;
138
+ } catch (e) {
139
+ return false;
140
+ }
141
+ }
142
+ };
143
+
144
+ // src/core/http.ts
145
+ var agcClient = import_axios2.default.create();
146
+ agcClient.interceptors.request.use(async (config2) => {
147
+ const cfg = getConfig();
148
+ if (!config2.baseURL) {
149
+ config2.baseURL = `https://${cfg.domain}`;
150
+ }
151
+ const token = await AuthManager.getAccessToken();
152
+ if (!config2.headers) {
153
+ config2.headers = {};
154
+ }
155
+ if (!config2.headers.Authorization) {
156
+ config2.headers.Authorization = `Bearer ${token}`;
157
+ }
158
+ if (!config2.headers.client_id) {
159
+ config2.headers.client_id = cfg.clientId;
160
+ }
161
+ if (config2.data !== void 0 && !config2.headers["Content-Type"]) {
162
+ config2.headers["Content-Type"] = "application/json";
163
+ }
164
+ return config2;
165
+ }, (error) => {
166
+ return Promise.reject(error);
167
+ });
168
+ agcClient.interceptors.response.use(
169
+ (res) => res,
170
+ (err) => {
171
+ if (err.response?.status === 403) {
172
+ const body = err.response?.data;
173
+ const msg = typeof body === "object" ? JSON.stringify(body, null, 2) : body;
174
+ err.message = err.message + (msg ? `
175
+ API \u54CD\u5E94: ${msg}` : "");
176
+ }
177
+ return Promise.reject(err);
178
+ }
179
+ );
180
+
181
+ // src/services/publish.ts
182
+ var PublishService = class {
183
+ /**
184
+ * 查询应用包名对应的appid
185
+ * @param packageName 需要查询的应用包名,多个包名以逗号分隔,最多支持50个
186
+ */
187
+ static async getAppIdList(packageName) {
188
+ const response = await agcClient.get("/api/publish/v2/appid-list", {
189
+ params: { packageName }
190
+ });
191
+ return response.data;
192
+ }
193
+ /**
194
+ * 查询应用信息
195
+ * @param appId 需要查询的应用ID
196
+ * @param lang 需要查询的语言 (例如: 'zh-CN'),不传则查询全部语言
197
+ */
198
+ static async getAppInfo(appId, lang) {
199
+ const params = { appId };
200
+ if (lang) {
201
+ params.lang = lang;
202
+ }
203
+ const response = await agcClient.get("/api/publish/v3/app-info", {
204
+ params
205
+ });
206
+ return response.data;
207
+ }
208
+ };
209
+
210
+ // src/services/upload.ts
211
+ var import_axios3 = __toESM(require("axios"));
212
+ var import_fs3 = __toESM(require("fs"));
213
+ var UploadService = class {
214
+ // ================= Raw APIs =================
215
+ static async getUploadUrl(req) {
216
+ const response = await agcClient.get("/api/publish/v2/upload-url/for-obs", {
217
+ params: req
218
+ });
219
+ return response.data;
220
+ }
221
+ static async initMultipart(req) {
222
+ const response = await agcClient.post("/api/publish/v2/upload/multipart/init", null, {
223
+ params: req
224
+ });
225
+ return response.data;
226
+ }
227
+ static async getMultipartParts(req) {
228
+ const { objectId, nspUploadId, parts } = req;
229
+ const response = await agcClient.post("/api/publish/v2/upload/multipart/parts", parts, {
230
+ params: { objectId, nspUploadId }
231
+ });
232
+ return response.data;
233
+ }
234
+ static async composeMultipart(req) {
235
+ const { objectId, nspUploadId, parts } = req;
236
+ const response = await agcClient.post("/api/publish/v2/upload/multipart/compose", parts, {
237
+ params: { objectId, nspUploadId }
238
+ });
239
+ return response.data;
240
+ }
241
+ // ================= High-level Operations =================
242
+ /**
243
+ * 封装好的上传文件核心流程(支持根据文件大小自动单文件或分片上传)
244
+ * 文件大小 < 5MB 时使用单文件上传,否则使用分片上传
245
+ */
246
+ static async uploadFile(options) {
247
+ const stat = import_fs3.default.statSync(options.filePath);
248
+ const fileName = options.filePath.split("/").pop() || "unknown";
249
+ if (stat.size < 5 * 1024 * 1024) {
250
+ await this.uploadSingleFile(options, fileName, stat.size);
251
+ } else {
252
+ await this.uploadMultipartFile(options, fileName, stat.size);
253
+ }
254
+ }
255
+ /**
256
+ * 单文件上传流程
257
+ */
258
+ static async uploadSingleFile(options, fileName, contentLength) {
259
+ const urlRes = await this.getUploadUrl({
260
+ appId: options.appId,
261
+ fileName,
262
+ contentLength,
263
+ releaseType: options.releaseType,
264
+ chineseMainlandFlag: options.chineseMainlandFlag
265
+ });
266
+ if (!urlRes.urlInfo) {
267
+ throw new Error(`Failed to get upload URL: ${JSON.stringify(urlRes.ret)}`);
268
+ }
269
+ const { url, headers } = urlRes.urlInfo;
270
+ const fileStream = import_fs3.default.createReadStream(options.filePath);
271
+ await import_axios3.default.put(url, fileStream, {
272
+ headers: {
273
+ ...headers,
274
+ "Content-Type": "application/octet-stream"
275
+ },
276
+ maxBodyLength: Infinity,
277
+ maxContentLength: Infinity
278
+ });
279
+ }
280
+ /**
281
+ * 分片上传流程
282
+ */
283
+ static async uploadMultipartFile(options, fileName, fileSize) {
284
+ const initRes = await this.initMultipart({
285
+ appId: options.appId,
286
+ fileName,
287
+ releaseType: options.releaseType,
288
+ chineseMainlandFlag: options.chineseMainlandFlag
289
+ });
290
+ const { objectId, nspUploadId, nspPartMinSize = 5242880 } = initRes;
291
+ if (!objectId || !nspUploadId) {
292
+ throw new Error(`Failed to init multipart upload: ${JSON.stringify(initRes.ret)}`);
293
+ }
294
+ const partSize = Number(nspPartMinSize);
295
+ const partsCount = Math.ceil(fileSize / partSize);
296
+ const partsReqBody = {};
297
+ for (let i = 1; i <= partsCount; i++) {
298
+ const start = (i - 1) * partSize;
299
+ const end = Math.min(start + partSize, fileSize);
300
+ partsReqBody[`additionalProp${i}`] = {
301
+ length: end - start
302
+ };
303
+ }
304
+ const partsRes = await this.getMultipartParts({
305
+ objectId,
306
+ nspUploadId,
307
+ parts: partsReqBody
308
+ });
309
+ const uploadInfoMap = partsRes.uploadInfoMap;
310
+ if (!uploadInfoMap) {
311
+ throw new Error(`Failed to get parts upload URL: ${JSON.stringify(partsRes.ret)}`);
312
+ }
313
+ const fd = import_fs3.default.openSync(options.filePath, "r");
314
+ const composeReqBody = {};
315
+ for (let i = 1; i <= partsCount; i++) {
316
+ const propKey = `additionalProp${i}`;
317
+ const uploadInfo = uploadInfoMap[propKey];
318
+ const start = (i - 1) * partSize;
319
+ const end = Math.min(start + partSize, fileSize);
320
+ const length = end - start;
321
+ const buffer = Buffer.alloc(length);
322
+ import_fs3.default.readSync(fd, buffer, 0, length, start);
323
+ const res = await import_axios3.default.put(uploadInfo.url, buffer, {
324
+ headers: {
325
+ ...uploadInfo.headers,
326
+ "Content-Type": "application/octet-stream"
327
+ },
328
+ maxBodyLength: Infinity,
329
+ maxContentLength: Infinity
330
+ });
331
+ const etag = res.headers["etag"];
332
+ composeReqBody[propKey] = {
333
+ partObjectId: uploadInfo.partObjectId || "",
334
+ etag
335
+ };
336
+ }
337
+ import_fs3.default.closeSync(fd);
338
+ await this.composeMultipart({
339
+ objectId,
340
+ nspUploadId,
341
+ parts: composeReqBody
342
+ });
343
+ }
344
+ };
345
+
346
+ // src/services/provision.ts
347
+ var ProvisionService = class {
348
+ // ================= Certificates =================
349
+ static async createCert(req) {
350
+ const response = await agcClient.post("/api/publish/v3/cert", req);
351
+ return response.data;
352
+ }
353
+ static async getCertList(req) {
354
+ const response = await agcClient.post("/api/publish/v3/cert/list", req);
355
+ return response.data;
356
+ }
357
+ static async deleteCert(req) {
358
+ const response = await agcClient.post("/api/publish/v2/cert/delete", req);
359
+ return response.data;
360
+ }
361
+ // ================= Devices =================
362
+ static async addDevice(req) {
363
+ const response = await agcClient.post("/api/publish/v2/device", req);
364
+ return response.data;
365
+ }
366
+ static async getDeviceList(req) {
367
+ const params = new URLSearchParams();
368
+ if (req.deviceName) params.append("deviceName", req.deviceName);
369
+ if (req.fromRecCount) params.append("fromRecCount", String(req.fromRecCount));
370
+ if (req.maxReqCount) params.append("maxReqCount", String(req.maxReqCount));
371
+ if (req.order) params.append("order", String(req.order));
372
+ const url = `/api/publish/v2/device/list?${params.toString()}`;
373
+ const response = await agcClient.get(url);
374
+ return response.data;
375
+ }
376
+ static async deleteDevice(req) {
377
+ const response = await agcClient.post("/api/publish/v2/device/delete", req);
378
+ return response.data;
379
+ }
380
+ // ================= Profile / Provision =================
381
+ static async createProvision(req) {
382
+ const response = await agcClient.post("/api/publish/v3/provision", req);
383
+ return response.data;
384
+ }
385
+ static async getProvisionList(req) {
386
+ const params = new URLSearchParams();
387
+ if (req.fromRecCount) params.append("fromRecCount", String(req.fromRecCount));
388
+ if (req.maxReqCount) params.append("maxReqCount", String(req.maxReqCount));
389
+ const headers = {
390
+ appId: req.appId
391
+ };
392
+ if (req.provisionId) {
393
+ headers.provisionId = req.provisionId;
394
+ }
395
+ const url = `/api/publish/v3/provision/list?${params.toString()}`;
396
+ const response = await agcClient.get(url, { headers });
397
+ return response.data;
398
+ }
399
+ static async updateProvision(req) {
400
+ const response = await agcClient.put("/api/publish/v3/provision", req);
401
+ return response.data;
402
+ }
403
+ static async deleteProvision(req) {
404
+ const params = new URLSearchParams();
405
+ if (req.id) params.append("id", req.id);
406
+ const url = `/api/publish/v2/provision?${params.toString()}`;
407
+ const response = await agcClient.delete(url);
408
+ return response.data;
409
+ }
410
+ // ================= Fingerprint =================
411
+ static async addFingerprint(req) {
412
+ const { appId, ...body } = req;
413
+ const headers = { appId };
414
+ const response = await agcClient.post("/api/provision/v1/fingerprints", body, { headers });
415
+ return response.data;
416
+ }
417
+ static async getFingerprintList(req) {
418
+ const headers = { appId: req.appId };
419
+ const response = await agcClient.get("/api/provision/v1/fingerprints", { headers });
420
+ return response.data;
421
+ }
422
+ static async deleteFingerprint(req) {
423
+ const { appId, ...body } = req;
424
+ const headers = { appId };
425
+ const response = await agcClient.delete("/api/provision/v1/fingerprints", { headers, data: body });
426
+ return response.data;
427
+ }
428
+ // ================= ACL Permission =================
429
+ static async applyACL(req) {
430
+ const { appId, ...body } = req;
431
+ const headers = { appId };
432
+ const response = await agcClient.post("/api/provision/v1/user/permission/apply", body, { headers });
433
+ return response.data;
434
+ }
435
+ static async getACLStatus(req) {
436
+ const headers = { appId: req.appId };
437
+ const response = await agcClient.get("/api/provision/v1/user/permission/apply/status", { headers });
438
+ return response.data;
439
+ }
440
+ static async getACLQuery(req) {
441
+ const headers = { appId: req.appId };
442
+ const response = await agcClient.get("/api/provision/v1/user/permission", { headers });
443
+ return response.data;
444
+ }
445
+ };
446
+ // Annotate the CommonJS export names for ESM import in node:
447
+ 0 && (module.exports = {
448
+ AuthService,
449
+ ProvisionService,
450
+ PublishService,
451
+ UploadService,
452
+ agcClient,
453
+ getConfig
454
+ });
455
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/services/auth.ts","../src/config/index.ts","../src/core/http.ts","../src/core/auth-mgr.ts","../src/services/publish.ts","../src/services/upload.ts","../src/services/provision.ts"],"sourcesContent":["export * from './services/auth';\nexport * from './services/publish';\nexport * from './services/upload';\nexport * from './services/provision';\nexport * from './core/http';\nexport * from './config';\n","import axios from 'axios';\nimport { TokenRequest, TokenResponse } from '../types/auth';\nimport { getConfig } from '../config';\n\nexport class AuthService {\n /**\n * 获取访问API的Token\n */\n static async getToken(): Promise<TokenResponse> {\n const config = getConfig();\n const url = `https://${config.domain}/api/oauth2/v1/token`;\n \n const payload: TokenRequest = {\n grant_type: 'client_credentials',\n client_id: config.clientId,\n client_secret: config.clientSecret,\n };\n\n const response = await axios.post<TokenResponse>(url, payload, {\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n\n return response.data;\n }\n}\n","import * as dotenv from 'dotenv';\nimport path from 'path';\nimport fs from 'fs';\n\n// 尝试从当前目录加载 .env\nconst envPath = path.resolve(process.cwd(), '.env');\nif (fs.existsSync(envPath)) {\n dotenv.config({ path: envPath });\n} else {\n dotenv.config();\n}\n\nexport interface AgcConfig {\n clientId: string;\n clientSecret: string;\n domain: string;\n}\n\nexport function getConfig(): AgcConfig {\n const clientId = process.env.AGC_CLIENT_ID;\n const clientSecret = process.env.AGC_CLIENT_SECRET;\n \n if (!clientId || !clientSecret) {\n throw new Error('Missing AGC credentials. Please set AGC_CLIENT_ID and AGC_CLIENT_SECRET environment variables.');\n }\n\n return {\n clientId,\n clientSecret,\n domain: process.env.AGC_DOMAIN || 'connect-api.cloud.huawei.com',\n };\n}\n","import axios from 'axios';\nimport { AuthManager } from './auth-mgr';\nimport { getConfig } from '../config';\n\nexport const agcClient = axios.create();\n\n// 请求拦截器:自动补充BaseURL、鉴权Token和client_id\nagcClient.interceptors.request.use(async (config) => {\n const cfg = getConfig();\n \n if (!config.baseURL) {\n config.baseURL = `https://${cfg.domain}`;\n }\n \n const token = await AuthManager.getAccessToken();\n \n if (!config.headers) {\n config.headers = {} as any;\n }\n \n if (!config.headers.Authorization) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n \n if (!config.headers.client_id) {\n config.headers.client_id = cfg.clientId;\n }\n\n // POST/PUT 等带 Body 的请求需显式设置 Content-Type(文档要求)\n if (config.data !== undefined && !config.headers['Content-Type']) {\n config.headers['Content-Type'] = 'application/json';\n }\n\n return config;\n}, (error) => {\n return Promise.reject(error);\n});\n\n// 响应拦截器:403 时输出完整错误信息便于调试\nagcClient.interceptors.response.use(\n (res) => res,\n (err) => {\n if (err.response?.status === 403) {\n const body = err.response?.data;\n const msg = typeof body === 'object' ? JSON.stringify(body, null, 2) : body;\n err.message = err.message + (msg ? `\\nAPI 响应: ${msg}` : '');\n }\n return Promise.reject(err);\n }\n);\n","import { AuthService } from '../services/auth';\nimport fs from 'fs';\nimport path from 'path';\nimport os from 'os';\n\nexport interface TokenCache {\n accessToken: string;\n expiresAt: number;\n}\n\nexport class AuthManager {\n private static cacheFile = path.join(os.homedir(), '.agc-cli-token.json');\n\n static async getAccessToken(): Promise<string> {\n const cache = this.readCache();\n // 提前5分钟判断过期,避免临界情况\n if (cache && cache.expiresAt > Date.now() + 5 * 60 * 1000) {\n return cache.accessToken;\n }\n\n // Token不存在或已过期,重新获取\n const res = await AuthService.getToken();\n if (res.access_token && res.expires_in) {\n const expiresAt = Date.now() + res.expires_in * 1000;\n this.writeCache({ accessToken: res.access_token, expiresAt });\n return res.access_token;\n }\n\n throw new Error(`Failed to get token: ${JSON.stringify(res.ret)}`);\n }\n\n private static readCache(): TokenCache | null {\n try {\n if (fs.existsSync(this.cacheFile)) {\n const data = fs.readFileSync(this.cacheFile, 'utf8');\n return JSON.parse(data);\n }\n } catch (e) {\n // 忽略读取错误\n }\n return null;\n }\n\n private static writeCache(cache: TokenCache) {\n try {\n fs.writeFileSync(this.cacheFile, JSON.stringify(cache, null, 2), 'utf8');\n } catch (e) {\n // 忽略写入错误\n }\n }\n\n /**\n * 清除缓存的 Token(登出)\n */\n static clearCache(): boolean {\n try {\n if (fs.existsSync(this.cacheFile)) {\n fs.unlinkSync(this.cacheFile);\n return true;\n }\n return false;\n } catch (e) {\n return false;\n }\n }\n}\n","import { agcClient } from '../core/http';\nimport { AppIdListResponse, AppInfoResponse } from '../types/publish';\n\nexport class PublishService {\n /**\n * 查询应用包名对应的appid\n * @param packageName 需要查询的应用包名,多个包名以逗号分隔,最多支持50个\n */\n static async getAppIdList(packageName: string): Promise<AppIdListResponse> {\n const response = await agcClient.get<AppIdListResponse>('/api/publish/v2/appid-list', {\n params: { packageName }\n });\n return response.data;\n }\n\n /**\n * 查询应用信息\n * @param appId 需要查询的应用ID\n * @param lang 需要查询的语言 (例如: 'zh-CN'),不传则查询全部语言\n */\n static async getAppInfo(appId: string, lang?: string): Promise<AppInfoResponse> {\n const params: any = { appId };\n if (lang) {\n params.lang = lang;\n }\n \n const response = await agcClient.get<AppInfoResponse>('/api/publish/v3/app-info', {\n params\n });\n return response.data;\n }\n}\n","import { agcClient } from '../core/http';\nimport axios from 'axios';\nimport fs from 'fs';\nimport {\n UploadUrlRequest, UploadUrlResponse,\n MultipartInitRequest, MultipartInitResponse,\n MultipartPartsRequest, MultipartPartsResponse,\n MultipartComposeRequest, MultipartComposeResponse,\n UploadFileOptions\n} from '../types/upload';\n\nexport class UploadService {\n // ================= Raw APIs =================\n\n static async getUploadUrl(req: UploadUrlRequest): Promise<UploadUrlResponse> {\n const response = await agcClient.get<UploadUrlResponse>('/api/publish/v2/upload-url/for-obs', {\n params: req\n });\n return response.data;\n }\n\n static async initMultipart(req: MultipartInitRequest): Promise<MultipartInitResponse> {\n const response = await agcClient.post<MultipartInitResponse>('/api/publish/v2/upload/multipart/init', null, {\n params: req\n });\n return response.data;\n }\n\n static async getMultipartParts(req: MultipartPartsRequest): Promise<MultipartPartsResponse> {\n const { objectId, nspUploadId, parts } = req;\n const response = await agcClient.post<MultipartPartsResponse>('/api/publish/v2/upload/multipart/parts', parts, {\n params: { objectId, nspUploadId }\n });\n return response.data;\n }\n\n static async composeMultipart(req: MultipartComposeRequest): Promise<MultipartComposeResponse> {\n const { objectId, nspUploadId, parts } = req;\n const response = await agcClient.post<MultipartComposeResponse>('/api/publish/v2/upload/multipart/compose', parts, {\n params: { objectId, nspUploadId }\n });\n return response.data;\n }\n\n // ================= High-level Operations =================\n\n /**\n * 封装好的上传文件核心流程(支持根据文件大小自动单文件或分片上传)\n * 文件大小 < 5MB 时使用单文件上传,否则使用分片上传\n */\n static async uploadFile(options: UploadFileOptions): Promise<void> {\n const stat = fs.statSync(options.filePath);\n const fileName = options.filePath.split('/').pop() || 'unknown';\n \n // 如果小于 5MB,可以直接使用单文件上传\n if (stat.size < 5 * 1024 * 1024) {\n await this.uploadSingleFile(options, fileName, stat.size);\n } else {\n await this.uploadMultipartFile(options, fileName, stat.size);\n }\n }\n\n /**\n * 单文件上传流程\n */\n private static async uploadSingleFile(\n options: UploadFileOptions,\n fileName: string,\n contentLength: number\n ): Promise<void> {\n // 1. 获取上传文件地址\n const urlRes = await this.getUploadUrl({\n appId: options.appId,\n fileName,\n contentLength,\n releaseType: options.releaseType,\n chineseMainlandFlag: options.chineseMainlandFlag\n });\n\n if (!urlRes.urlInfo) {\n throw new Error(`Failed to get upload URL: ${JSON.stringify(urlRes.ret)}`);\n }\n\n const { url, headers } = urlRes.urlInfo;\n\n // 2. 上传文件\n const fileStream = fs.createReadStream(options.filePath);\n await axios.put(url, fileStream, {\n headers: {\n ...headers,\n 'Content-Type': 'application/octet-stream',\n },\n maxBodyLength: Infinity,\n maxContentLength: Infinity\n });\n }\n\n /**\n * 分片上传流程\n */\n private static async uploadMultipartFile(\n options: UploadFileOptions,\n fileName: string,\n fileSize: number\n ): Promise<void> {\n // 1. 初始化分片上传\n const initRes = await this.initMultipart({\n appId: options.appId,\n fileName,\n releaseType: options.releaseType,\n chineseMainlandFlag: options.chineseMainlandFlag\n });\n\n const { objectId, nspUploadId, nspPartMinSize = 5242880 } = initRes;\n if (!objectId || !nspUploadId) {\n throw new Error(`Failed to init multipart upload: ${JSON.stringify(initRes.ret)}`);\n }\n\n const partSize = Number(nspPartMinSize);\n const partsCount = Math.ceil(fileSize / partSize);\n\n // 2. 构造分片请求信息以获取各分片的上传地址\n const partsReqBody: Record<string, { length: number }> = {};\n for (let i = 1; i <= partsCount; i++) {\n const start = (i - 1) * partSize;\n const end = Math.min(start + partSize, fileSize);\n partsReqBody[`additionalProp${i}`] = {\n length: end - start\n };\n }\n\n const partsRes = await this.getMultipartParts({\n objectId,\n nspUploadId,\n parts: partsReqBody\n });\n\n const uploadInfoMap = partsRes.uploadInfoMap;\n if (!uploadInfoMap) {\n throw new Error(`Failed to get parts upload URL: ${JSON.stringify(partsRes.ret)}`);\n }\n\n // 3. 上传各分片\n const fd = fs.openSync(options.filePath, 'r');\n const composeReqBody: Record<string, { partObjectId: string; etag: string }> = {};\n\n for (let i = 1; i <= partsCount; i++) {\n const propKey = `additionalProp${i}`;\n const uploadInfo = uploadInfoMap[propKey];\n \n const start = (i - 1) * partSize;\n const end = Math.min(start + partSize, fileSize);\n const length = end - start;\n const buffer = Buffer.alloc(length);\n fs.readSync(fd, buffer, 0, length, start);\n\n const res = await axios.put(uploadInfo.url, buffer, {\n headers: {\n ...uploadInfo.headers,\n 'Content-Type': 'application/octet-stream'\n },\n maxBodyLength: Infinity,\n maxContentLength: Infinity\n });\n\n // 记录ETag供合并分片使用\n const etag = res.headers['etag'];\n composeReqBody[propKey] = {\n partObjectId: uploadInfo.partObjectId || \"\",\n etag: etag\n };\n }\n fs.closeSync(fd);\n\n // 4. 合并分片\n await this.composeMultipart({\n objectId,\n nspUploadId,\n parts: composeReqBody\n });\n }\n}\n","import { agcClient } from '../core/http';\nimport {\n CertCreateRequest, CertCreateResponse,\n CertListRequest, CertListResponse,\n CertDeleteRequest, CertDeleteResponse,\n DeviceAddRequest, DeviceAddResponse,\n DeviceListRequest, DeviceListResponse,\n DeviceDeleteRequest, DeviceDeleteResponse,\n ProvisionCreateRequest, ProvisionCreateResponse,\n ProvisionListRequest, ProvisionListResponse,\n ProvisionUpdateRequest, ProvisionUpdateResponse,\n ProvisionDeleteRequest, ProvisionDeleteResponse,\n FingerprintAddRequest, FingerprintAddResponse,\n FingerprintListRequest, FingerprintListResponse,\n FingerprintDeleteRequest, FingerprintDeleteResponse,\n ACLApplyRequest, ACLApplyResponse,\n ACLStatusRequest, ACLStatusResponse,\n ACLQueryRequest, ACLQueryResponse\n} from '../types/provision';\n\nexport class ProvisionService {\n // ================= Certificates =================\n static async createCert(req: CertCreateRequest): Promise<CertCreateResponse> {\n const response = await agcClient.post<CertCreateResponse>('/api/publish/v3/cert', req);\n return response.data;\n }\n\n static async getCertList(req: CertListRequest): Promise<CertListResponse> {\n const response = await agcClient.post<CertListResponse>('/api/publish/v3/cert/list', req);\n return response.data;\n }\n\n static async deleteCert(req: CertDeleteRequest): Promise<CertDeleteResponse> {\n const response = await agcClient.post<CertDeleteResponse>('/api/publish/v2/cert/delete', req);\n return response.data;\n }\n\n // ================= Devices =================\n static async addDevice(req: DeviceAddRequest): Promise<DeviceAddResponse> {\n const response = await agcClient.post<DeviceAddResponse>('/api/publish/v2/device', req);\n return response.data;\n }\n\n static async getDeviceList(req: DeviceListRequest): Promise<DeviceListResponse> {\n const params = new URLSearchParams();\n if (req.deviceName) params.append('deviceName', req.deviceName);\n if (req.fromRecCount) params.append('fromRecCount', String(req.fromRecCount));\n if (req.maxReqCount) params.append('maxReqCount', String(req.maxReqCount));\n if (req.order) params.append('order', String(req.order));\n \n const url = `/api/publish/v2/device/list?${params.toString()}`;\n const response = await agcClient.get<DeviceListResponse>(url);\n return response.data;\n }\n\n static async deleteDevice(req: DeviceDeleteRequest): Promise<DeviceDeleteResponse> {\n const response = await agcClient.post<DeviceDeleteResponse>('/api/publish/v2/device/delete', req);\n return response.data;\n }\n\n // ================= Profile / Provision =================\n static async createProvision(req: ProvisionCreateRequest): Promise<ProvisionCreateResponse> {\n const response = await agcClient.post<ProvisionCreateResponse>('/api/publish/v3/provision', req);\n return response.data;\n }\n\n static async getProvisionList(req: ProvisionListRequest): Promise<ProvisionListResponse> {\n const params = new URLSearchParams();\n if (req.fromRecCount) params.append('fromRecCount', String(req.fromRecCount));\n if (req.maxReqCount) params.append('maxReqCount', String(req.maxReqCount));\n \n // Some parameters like appId and provisionId are sent via headers in the API, we need to pass them in config\n const headers: Record<string, string> = {\n appId: req.appId\n };\n if (req.provisionId) {\n headers.provisionId = req.provisionId;\n }\n\n const url = `/api/publish/v3/provision/list?${params.toString()}`;\n const response = await agcClient.get<ProvisionListResponse>(url, { headers });\n return response.data;\n }\n\n static async updateProvision(req: ProvisionUpdateRequest): Promise<ProvisionUpdateResponse> {\n const response = await agcClient.put<ProvisionUpdateResponse>('/api/publish/v3/provision', req);\n return response.data;\n }\n\n static async deleteProvision(req: ProvisionDeleteRequest): Promise<ProvisionDeleteResponse> {\n const params = new URLSearchParams();\n if (req.id) params.append('id', req.id);\n const url = `/api/publish/v2/provision?${params.toString()}`;\n const response = await agcClient.delete<ProvisionDeleteResponse>(url);\n return response.data;\n }\n\n // ================= Fingerprint =================\n static async addFingerprint(req: FingerprintAddRequest): Promise<FingerprintAddResponse> {\n const { appId, ...body } = req;\n const headers = { appId };\n const response = await agcClient.post<FingerprintAddResponse>('/api/provision/v1/fingerprints', body, { headers });\n return response.data;\n }\n\n static async getFingerprintList(req: FingerprintListRequest): Promise<FingerprintListResponse> {\n const headers = { appId: req.appId };\n const response = await agcClient.get<FingerprintListResponse>('/api/provision/v1/fingerprints', { headers });\n return response.data;\n }\n\n static async deleteFingerprint(req: FingerprintDeleteRequest): Promise<FingerprintDeleteResponse> {\n const { appId, ...body } = req;\n const headers = { appId };\n // Axios delete with body requires 'data' config property\n const response = await agcClient.delete<FingerprintDeleteResponse>('/api/provision/v1/fingerprints', { headers, data: body });\n return response.data;\n }\n\n // ================= ACL Permission =================\n static async applyACL(req: ACLApplyRequest): Promise<ACLApplyResponse> {\n const { appId, ...body } = req;\n const headers = { appId };\n const response = await agcClient.post<ACLApplyResponse>('/api/provision/v1/user/permission/apply', body, { headers });\n return response.data;\n }\n\n static async getACLStatus(req: ACLStatusRequest): Promise<ACLStatusResponse> {\n const headers = { appId: req.appId };\n const response = await agcClient.get<ACLStatusResponse>('/api/provision/v1/user/permission/apply/status', { headers });\n return response.data;\n }\n\n static async getACLQuery(req: ACLQueryRequest): Promise<ACLQueryResponse> {\n const headers = { appId: req.appId };\n const response = await agcClient.get<ACLQueryResponse>('/api/provision/v1/user/permission', { headers });\n return response.data;\n }\n}\n"],"mappings":"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","names":["path","fs","config","axios","import_axios","import_fs","import_path","path","os","fs","axios","config","import_axios","import_fs","fs","axios"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,17 @@
1
+ import {
2
+ AuthService,
3
+ ProvisionService,
4
+ PublishService,
5
+ UploadService,
6
+ agcClient,
7
+ getConfig
8
+ } from "./chunk-CSXIZ7GI.mjs";
9
+ export {
10
+ AuthService,
11
+ ProvisionService,
12
+ PublishService,
13
+ UploadService,
14
+ agcClient,
15
+ getConfig
16
+ };
17
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "agc-api-cli",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.mjs",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "agc-cli": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "build:skill": "tsup --config tsup.config.standalone.ts && chmod +x .cursor/skills/agc-cli-orchestration/bin/agc-cli.js",
17
+ "dev": "tsup --watch",
18
+ "start": "node dist/cli.js",
19
+ "test": "echo \"Error: no test specified\" && exit 1"
20
+ },
21
+ "keywords": [],
22
+ "author": "",
23
+ "license": "ISC",
24
+ "description": "AppGallery Connect API CLI Tool",
25
+ "dependencies": {
26
+ "axios": "^1.13.5",
27
+ "commander": "^14.0.3",
28
+ "dotenv": "^17.3.1"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^25.3.0",
32
+ "tsup": "^8.5.1",
33
+ "typescript": "^5.9.3"
34
+ }
35
+ }