cloudcc-cli 2.4.1 → 2.4.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.
Files changed (44) hide show
  1. package/README.md +42 -0
  2. package/bin/index.js +5 -0
  3. package/cloudcc-dev-skill/SKILL.md +6 -12
  4. package/cloudcc-dev-skill/config.json +2 -2
  5. package/package.json +2 -2
  6. package/src/classes/create.js +1 -1
  7. package/src/config/use.js +20 -5
  8. package/src/dupeCatcher/create.js +76 -0
  9. package/src/dupeCatcher/delete.js +69 -0
  10. package/src/dupeCatcher/detail.js +57 -0
  11. package/src/dupeCatcher/doc.js +11 -0
  12. package/src/dupeCatcher/docs/devguide.md +125 -0
  13. package/src/dupeCatcher/docs/introduction.md +21 -0
  14. package/src/dupeCatcher/get.js +88 -0
  15. package/src/dupeCatcher/index.js +14 -0
  16. package/src/html/doc.js +35 -0
  17. package/src/html/docs/devguide.md +67 -0
  18. package/src/html/docs/introduction.md +4 -0
  19. package/src/html/index.js +11 -0
  20. package/src/openapi/cloudcc-openapi-sdk.js +1085 -0
  21. package/src/openapi/doc.js +30 -0
  22. package/src/openapi/docs/devguide.md +65 -0
  23. package/src/openapi/docs/introduction.md +43 -0
  24. package/src/openapi/get.js +45 -0
  25. package/src/openapi/index.js +12 -0
  26. package/src/plugin/publish1.js +1 -1
  27. package/src/plugin/pull.js +2 -2
  28. package/src/sharingRule/doc.js +46 -0
  29. package/src/sharingRule/docs/devguide.md +28 -0
  30. package/src/sharingRule/docs/introduction.md +7 -0
  31. package/src/sharingRule/get.js +48 -0
  32. package/src/sharingRule/index.js +9 -0
  33. package/src/site/doc.js +35 -0
  34. package/src/site/docs/devguide.md +209 -0
  35. package/src/site/docs/introduction.md +4 -0
  36. package/src/site/index.js +11 -0
  37. package/src/triggers/docs/devguide.md +1 -2
  38. package/src/triggers/get.js +1 -2
  39. package/src/version/doctor.js +11 -4
  40. package/src/version/listModuleCommands.js +20 -0
  41. package/template/index.js +2 -2
  42. package/utils/config.js +129 -21
  43. package/cloudcc-dev-skill/cloudcc-dev-html.md +0 -42
  44. package/template/cloudcc-cli.configjs +0 -7
@@ -0,0 +1,1085 @@
1
+ /**
2
+ * CloudCC OpenAPI 浏览器端 SDK(已内置账号登录 + 换票两个接口)
3
+ * 文档:https://help.cloudcc.cn/product03/apigai-lan/
4
+ *
5
+ * 依赖:crypto-js、jsencrypt(登录加密用)
6
+ *
7
+ * 用法:
8
+ * const api = new CloudCCOpenAPI({ ClientId, SecretKey, loginsvcurl });
9
+ * await api.login('账号', '密码');
10
+ * const res = await api.cquery({ ... });
11
+ *
12
+ * 兼容:全局仍挂载 AccountPasswordLogin(与历史脚本同名 API)
13
+ */
14
+ (function (root, factory) {
15
+ var out = factory();
16
+ var CloudCCOpenAPI = out.CloudCCOpenAPI;
17
+ root.CloudCCOpenAPI = CloudCCOpenAPI;
18
+ root.AccountPasswordLogin = out.AccountPasswordLogin;
19
+ if (typeof module === 'object' && module.exports) {
20
+ module.exports = CloudCCOpenAPI;
21
+ module.exports.AccountPasswordLogin = out.AccountPasswordLogin;
22
+ module.exports.DEFAULT_LOGIN_SVC_BASE = out.DEFAULT_LOGIN_SVC_BASE;
23
+ }
24
+ })(typeof self !== 'undefined' ? self : this, function () {
25
+ 'use strict';
26
+
27
+ var DEFAULT_LOGIN_SVC_BASE = 'https://global.apis.cloudcc.cn/login';
28
+
29
+ var RSA_PUBLIC_KEY =
30
+ 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApwU/yGIaOnJuDqg9nV8FEwPL5BudK/l8cHaCcAy9sL56jtX1pHgvSpHW5ux2s2R+YGsdhRP1IJ9GBXFZre+DWmTf+rvRfzE26hKdRLMgYJnUjr1fyCcsRdDgBzjiDzdA8xCNSVt97ATE+1syX2k9Bwjoix3pX6rWOE/kKJw/yNOo8E6bJ6AWc/TFnmQ7AM0eatT3a6/uLSCKm8w9r95Jy/YQ37+1xN+prmxcOvZi+SJpE5V4fO7S7PD82TUCSQE1B7eUCitByJ/9DTNvZ6dYFP8/RFz8Ob+n3j7IcwcYherZKHr+F//TIPR+9xyluh5mNIyCw/MoryXHZnwxVTbT4wIDAQAB';
31
+
32
+ function getUuid() {
33
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
34
+ var r = (Math.random() * 16) | 0;
35
+ var v = c === 'x' ? r : (r & 0x3) | 0x8;
36
+ return v.toString(16);
37
+ });
38
+ }
39
+
40
+ function getBrowserName() {
41
+ var ua = navigator.userAgent.toLowerCase();
42
+ var map = {
43
+ IE: window.ActiveXObject || 'ActiveXObject' in window,
44
+ Chrome: ua.indexOf('chrome') > -1 && ua.indexOf('safari') > -1,
45
+ Firefox: ua.indexOf('firefox') > -1,
46
+ Opera: ua.indexOf('opera') > -1,
47
+ Safari: ua.indexOf('safari') > -1 && ua.indexOf('chrome') === -1,
48
+ Edge: ua.indexOf('edge') > -1,
49
+ QQBrowser: /qqbrowser/.test(ua),
50
+ WeixinBrowser: /MicroMessenger/i.test(ua)
51
+ };
52
+ var name = '';
53
+ for (var k in map) {
54
+ if (map[k]) name = k;
55
+ }
56
+ return name || 'Unknown';
57
+ }
58
+
59
+ function getBrowserVersion() {
60
+ var ua = navigator.userAgent.toLowerCase();
61
+ var browser = {};
62
+ var s;
63
+ (s = ua.match(/msie ([\d.]+)/))
64
+ ? (browser.ie = s[1])
65
+ : (s = ua.match(/firefox\/([\d.]+)/))
66
+ ? (browser.firefox = s[1])
67
+ : (s = ua.match(/chrome\/([\d.]+)/))
68
+ ? (browser.chrome = s[1])
69
+ : (s = ua.match(/opera.([\d.]+)/))
70
+ ? (browser.opera = s[1])
71
+ : (s = ua.match(/version\/([\d.]+).*safari/))
72
+ ? (browser.safari = s[1])
73
+ : 0;
74
+ if (browser.ie) return 'IE ' + browser.ie;
75
+ if (browser.firefox) return browser.firefox;
76
+ if (browser.chrome) return browser.chrome;
77
+ if (browser.opera) return browser.opera;
78
+ if (browser.safari) return browser.safari;
79
+ return '未知浏览器';
80
+ }
81
+
82
+ function getOperationSys() {
83
+ var OS = '';
84
+ var ua = navigator.userAgent.toLowerCase();
85
+ var map = {};
86
+ map.Windows = navigator.platform === 'Win32' || navigator.platform === 'Windows';
87
+ map.Mac =
88
+ navigator.platform === 'Mac68K' ||
89
+ navigator.platform === 'MacPPC' ||
90
+ navigator.platform === 'Macintosh' ||
91
+ navigator.platform === 'MacIntel';
92
+ map.iphone = ua.indexOf('iphone') > -1;
93
+ map.ipod = ua.indexOf('ipod') > -1;
94
+ map.ipad = ua.indexOf('ipad') > -1;
95
+ map.Android = ua.indexOf('android') > -1;
96
+ for (var i in map) {
97
+ if (map[i]) OS = i;
98
+ }
99
+ return OS || 'Unknown';
100
+ }
101
+
102
+ function getClientEnvironment(overrides) {
103
+ overrides = overrides || {};
104
+ return {
105
+ explorer: overrides.explorer != null ? overrides.explorer : getBrowserName() + getBrowserVersion(),
106
+ operatingSystem: overrides.operatingSystem != null ? overrides.operatingSystem : getOperationSys()
107
+ };
108
+ }
109
+
110
+ function aesEncryptUtf8Key(word, aesKeyStr) {
111
+ var key = CryptoJS.enc.Utf8.parse(aesKeyStr);
112
+ var srcs = CryptoJS.enc.Utf8.parse(word);
113
+ var encrypted = CryptoJS.AES.encrypt(srcs, key, {
114
+ mode: CryptoJS.mode.ECB,
115
+ padding: CryptoJS.pad.Pkcs7
116
+ });
117
+ return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
118
+ }
119
+
120
+ function encryptedAesKeyBase64(data) {
121
+ var encrypt = new JSEncrypt();
122
+ encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----\n' + RSA_PUBLIC_KEY + '\n-----END PUBLIC KEY-----');
123
+ var aesKey = CryptoJS.lib.WordArray.random(16).toString();
124
+ var sk = encrypt.encrypt(aesKey).toString();
125
+ var rp = aesEncryptUtf8Key(JSON.stringify(data), aesKey);
126
+ return { sk: sk, rp: rp };
127
+ }
128
+
129
+ var MIXKEY = ['username', 'password', 'password2', 'mobilePhone', 'verificationCode'];
130
+
131
+ function jsToFormData(obj) {
132
+ var mixobj = {};
133
+ var formData = new FormData();
134
+ Object.keys(obj).forEach(function (key) {
135
+ if (obj[key] instanceof Array) {
136
+ obj[key].forEach(function (item) {
137
+ formData.append(key, item);
138
+ });
139
+ return;
140
+ }
141
+ if (MIXKEY.indexOf(key) > -1) {
142
+ mixobj[key] = obj[key];
143
+ } else {
144
+ formData.append(key, obj[key]);
145
+ }
146
+ });
147
+ var pair = encryptedAesKeyBase64(mixobj);
148
+ formData.append('sk', pair.sk);
149
+ formData.append('rp', pair.rp);
150
+ return formData;
151
+ }
152
+
153
+ function buildAccountPasswordFormData(username, password, options) {
154
+ options = options || {};
155
+ var env = getClientEnvironment(options);
156
+ var parameter1 = {
157
+ password: password,
158
+ password2: CryptoJS.SHA512(password).toString(),
159
+ username: username,
160
+ explorer: env.explorer,
161
+ operatingSystem: env.operatingSystem,
162
+ rtnURL: options.rtnURL != null ? options.rtnURL : '',
163
+ serviceName: options.serviceName != null ? options.serviceName : ''
164
+ };
165
+ return jsToFormData(parameter1);
166
+ }
167
+
168
+ function logonUrl(loginSvcBase) {
169
+ return loginSvcBase.replace(/\/$/, '') + '/signin/logon';
170
+ }
171
+
172
+ function openApiConvertUrl(apiSvc) {
173
+ return apiSvc.replace(/\/$/, '') + '/api/cauth/convert';
174
+ }
175
+
176
+ function getGlobalFetch() {
177
+ return typeof fetch === 'function' ? fetch.bind(globalThis) : null;
178
+ }
179
+
180
+ /**
181
+ * POST {loginSvcBase}/signin/logon
182
+ */
183
+ function loginWithAccountPasswordImpl(opts, fetchImpl) {
184
+ if (!opts || !opts.loginSvcBase || !opts.username) {
185
+ return Promise.reject(new Error('loginSvcBase 与 username 为必填'));
186
+ }
187
+ if (typeof CryptoJS === 'undefined' || typeof JSEncrypt === 'undefined') {
188
+ return Promise.reject(new Error('请先引入 crypto-js 与 jsencrypt'));
189
+ }
190
+ if (!fetchImpl) return Promise.reject(new Error('fetch 不可用'));
191
+ var url = logonUrl(opts.loginSvcBase);
192
+ var formData = buildAccountPasswordFormData(opts.username, opts.password || '', {
193
+ rtnURL: opts.rtnURL,
194
+ serviceName: opts.serviceName,
195
+ explorer: opts.env && opts.env.explorer,
196
+ operatingSystem: opts.env && opts.env.operatingSystem
197
+ });
198
+ var headers = { requestId: getUuid() };
199
+ var fetchInit = Object.assign(
200
+ {
201
+ method: 'POST',
202
+ body: formData,
203
+ headers: headers
204
+ },
205
+ opts.fetchInit || {}
206
+ );
207
+ return fetchImpl(url, fetchInit)
208
+ .then(function (res) {
209
+ return res.json();
210
+ })
211
+ .then(function (body) {
212
+ var code = body.code != null ? body.code : 200;
213
+ if (code !== 200) {
214
+ var msg = body.msg == null ? '请求失败' : body.msg;
215
+ var err = new Error(msg);
216
+ err.responseBody = body;
217
+ throw err;
218
+ }
219
+ return body;
220
+ });
221
+ }
222
+
223
+ /**
224
+ * POST {apiSvc}/api/cauth/convert
225
+ */
226
+ function convertBusinessTokenToOpenApiImpl(opts, fetchImpl) {
227
+ if (!opts || !opts.apiSvc || !opts.userToken || opts.clientId === undefined || opts.clientId === '') {
228
+ return Promise.reject(new Error('apiSvc、userToken、clientId 为必填'));
229
+ }
230
+ if (opts.secretKey === undefined) {
231
+ return Promise.reject(new Error('secretKey 为必填'));
232
+ }
233
+ if (!fetchImpl) return Promise.reject(new Error('fetch 不可用'));
234
+ var url = openApiConvertUrl(opts.apiSvc);
235
+ var tokenHeader = opts.accessTokenHeaderName || 'accessToken';
236
+ var mergedHeaders = Object.assign(
237
+ {
238
+ 'Content-Type': 'application/json; charset=utf-8',
239
+ requestId: getUuid()
240
+ },
241
+ opts.fetchInit && opts.fetchInit.headers
242
+ );
243
+ mergedHeaders[tokenHeader] = opts.userToken;
244
+ var fetchInit = Object.assign({}, opts.fetchInit, {
245
+ method: 'POST',
246
+ headers: mergedHeaders,
247
+ body: JSON.stringify({
248
+ clientId: opts.clientId,
249
+ secretKey: opts.secretKey
250
+ })
251
+ });
252
+ return fetchImpl(url, fetchInit)
253
+ .then(function (res) {
254
+ return res.json();
255
+ })
256
+ .then(function (body) {
257
+ var code = body.code != null ? body.code : 200;
258
+ if (code !== 200) {
259
+ var msg0 = body.msg == null ? '请求失败' : body.msg;
260
+ var err0 = new Error(msg0);
261
+ err0.responseBody = body;
262
+ throw err0;
263
+ }
264
+ if (!body.result) {
265
+ var info = body.returnInfo != null ? body.returnInfo : '未知错误';
266
+ var err = new Error('OpenAPI token 转换失败: ' + info);
267
+ err.responseBody = body;
268
+ throw err;
269
+ }
270
+ if (body.data === undefined || body.data === null) {
271
+ var err2 = new Error('OpenAPI token 转换失败: 响应无 data');
272
+ err2.responseBody = body;
273
+ throw err2;
274
+ }
275
+ return body.data;
276
+ });
277
+ }
278
+
279
+ function loginThenOpenApiTokenImpl(opts, fetchImpl) {
280
+ if (!opts || !opts.apiSvc || opts.clientId === undefined || opts.secretKey === undefined) {
281
+ return Promise.reject(new Error('apiSvc、clientId、secretKey 为必填'));
282
+ }
283
+ return loginWithAccountPasswordImpl(opts, fetchImpl).then(function (body) {
284
+ if (!body.result || !body.data) {
285
+ var e = new Error(body.msg || '登录失败');
286
+ e.responseBody = body;
287
+ throw e;
288
+ }
289
+ var userToken = body.data.accessToken;
290
+ if (!userToken) {
291
+ var e2 = new Error('登录响应中无 data.accessToken,无法换取 OpenAPI token');
292
+ e2.responseBody = body;
293
+ throw e2;
294
+ }
295
+ return convertBusinessTokenToOpenApiImpl(
296
+ {
297
+ apiSvc: opts.apiSvc,
298
+ userToken: userToken,
299
+ clientId: opts.clientId,
300
+ secretKey: opts.secretKey,
301
+ accessTokenHeaderName: opts.accessTokenHeaderName,
302
+ fetchInit: opts.convertFetchInit
303
+ },
304
+ fetchImpl
305
+ ).then(function (openApiToken) {
306
+ return { login: body, openApiToken: openApiToken };
307
+ });
308
+ });
309
+ }
310
+
311
+ var AccountPasswordLogin = {
312
+ getUuid: getUuid,
313
+ getClientEnvironment: getClientEnvironment,
314
+ buildAccountPasswordFormData: buildAccountPasswordFormData,
315
+ logonUrl: logonUrl,
316
+ openApiConvertUrl: openApiConvertUrl,
317
+ convertBusinessTokenToOpenApi: function (opts) {
318
+ return convertBusinessTokenToOpenApiImpl(opts, getGlobalFetch());
319
+ },
320
+ loginThenOpenApiToken: function (opts) {
321
+ return loginThenOpenApiTokenImpl(opts, getGlobalFetch());
322
+ },
323
+ loginWithAccountPassword: function (opts) {
324
+ return loginWithAccountPasswordImpl(opts, getGlobalFetch());
325
+ },
326
+ DEFAULT_LOGIN_SVC_BASE: DEFAULT_LOGIN_SVC_BASE
327
+ };
328
+
329
+ function trimUrl(url) {
330
+ if (!url || typeof url !== 'string') return '';
331
+ return url.replace(/\/+$/, '');
332
+ }
333
+
334
+ function stringifyDataIfNeeded(data) {
335
+ if (data == null) return data;
336
+ if (typeof data === 'string') return data;
337
+ return JSON.stringify(data);
338
+ }
339
+
340
+ /**
341
+ * @typedef {Object} CloudCCOpenAPIOptions
342
+ * @property {string} [clientId] 与 ClientId 二选一
343
+ * @property {string} [ClientId]
344
+ * @property {string} [secretKey] 与 SecretKey 二选一
345
+ * @property {string} [SecretKey]
346
+ * @property {string} [loginSvcUrl] 登录服务根地址,与 loginsvcurl 二选一
347
+ * @property {string} [loginsvcurl]
348
+ * @property {typeof fetch} [fetch] 可选
349
+ */
350
+
351
+ function CloudCCOpenAPI(options) {
352
+ if (!options) throw new Error('CloudCCOpenAPI: 需要 options');
353
+ var o = options;
354
+ var clientId = o.clientId != null ? o.clientId : o.ClientId;
355
+ var secretKey = o.secretKey != null ? o.secretKey : o.SecretKey;
356
+ var loginSvcUrl =
357
+ o.loginSvcUrl != null ? o.loginSvcUrl : o.loginsvcurl != null ? o.loginsvcurl : o.loginSvcURL;
358
+ if (clientId === undefined || clientId === '' || secretKey === undefined || secretKey === '') {
359
+ throw new Error('CloudCCOpenAPI: clientId(或 ClientId)与 secretKey(或 SecretKey)为必填');
360
+ }
361
+ if (!loginSvcUrl) {
362
+ throw new Error('CloudCCOpenAPI: loginSvcUrl(或 loginsvcurl)为必填');
363
+ }
364
+ this.clientId = clientId;
365
+ this.secretKey = secretKey;
366
+ this.loginSvcUrl = trimUrl(loginSvcUrl);
367
+ this.gatewayUrl = '';
368
+ this.apiSvcUrl = '';
369
+ this.baseUrl = '';
370
+ this.accessToken = '';
371
+ this._lastLogin = null;
372
+ this._fetch = o.fetch || (typeof fetch === 'function' ? fetch.bind(globalThis) : null);
373
+ if (!this._fetch) throw new Error('CloudCCOpenAPI: 当前环境无 fetch,请传入 options.fetch');
374
+ }
375
+
376
+ /**
377
+ * 账号密码登录:从返回中取 gatewayUrl,拼 apisvc、lightningapi,再换 OpenAPI token
378
+ * @param {string} username
379
+ * @param {string} password
380
+ * @param {object} [opts] rtnURL、serviceName、env、fetchInit、accessTokenHeaderName、convertFetchInit
381
+ * @returns {Promise<{ gatewayUrl: string, apiSvcUrl: string, baseUrl: string, openApiToken: string, login: object }>}
382
+ */
383
+ CloudCCOpenAPI.prototype.login = function (username, password, opts) {
384
+ var self = this;
385
+ opts = opts || {};
386
+ if (!username) {
387
+ return Promise.reject(new Error('CloudCCOpenAPI: username 为必填'));
388
+ }
389
+ return loginWithAccountPasswordImpl(
390
+ {
391
+ loginSvcBase: self.loginSvcUrl,
392
+ username: username,
393
+ password: password || '',
394
+ rtnURL: opts.rtnURL,
395
+ serviceName: opts.serviceName,
396
+ env: opts.env,
397
+ fetchInit: opts.fetchInit
398
+ },
399
+ self._fetch
400
+ ).then(function (body) {
401
+ if (!body.result || !body.data) {
402
+ var e = new Error(body.msg || '登录失败');
403
+ e.responseBody = body;
404
+ throw e;
405
+ }
406
+ var gw = body.data.gatewayUrl;
407
+ if (!gw || typeof gw !== 'string') {
408
+ var e2 = new Error('CloudCCOpenAPI: 登录响应中无 data.gatewayUrl');
409
+ e2.responseBody = body;
410
+ throw e2;
411
+ }
412
+ gw = trimUrl(gw);
413
+ self.gatewayUrl = gw;
414
+ self.apiSvcUrl = gw + '/apisvc';
415
+ self.baseUrl = gw + '/lightningapi';
416
+ var userToken = body.data.accessToken;
417
+ if (!userToken) {
418
+ var e3 = new Error('CloudCCOpenAPI: 登录响应中无 data.accessToken');
419
+ e3.responseBody = body;
420
+ throw e3;
421
+ }
422
+ return convertBusinessTokenToOpenApiImpl(
423
+ {
424
+ apiSvc: self.apiSvcUrl,
425
+ userToken: userToken,
426
+ clientId: self.clientId,
427
+ secretKey: self.secretKey,
428
+ accessTokenHeaderName: opts.accessTokenHeaderName,
429
+ fetchInit: opts.convertFetchInit
430
+ },
431
+ self._fetch
432
+ ).then(function (openApiToken) {
433
+ self.accessToken = openApiToken;
434
+ self._lastLogin = body;
435
+ return {
436
+ gatewayUrl: self.gatewayUrl,
437
+ apiSvcUrl: self.apiSvcUrl,
438
+ baseUrl: self.baseUrl,
439
+ openApiToken: openApiToken,
440
+ login: body
441
+ };
442
+ });
443
+ });
444
+ };
445
+
446
+ CloudCCOpenAPI.prototype._ensureSession = function () {
447
+ if (!this.baseUrl || !this.accessToken) {
448
+ throw new Error('CloudCCOpenAPI: 请先调用 login(username, password)');
449
+ }
450
+ };
451
+
452
+ /** 手动覆盖 OpenAPI 根(一般无需;登录成功后会自动设置) */
453
+ CloudCCOpenAPI.prototype.setBaseUrl = function (url) {
454
+ if (!url) throw new Error('CloudCCOpenAPI: baseUrl 不能为空');
455
+ this.baseUrl = trimUrl(url);
456
+ };
457
+
458
+ CloudCCOpenAPI.prototype.setAccessToken = function (token) {
459
+ this.accessToken = token || '';
460
+ };
461
+
462
+ CloudCCOpenAPI.prototype._requireBrowserCookie = function () {
463
+ if (typeof document === 'undefined') {
464
+ throw new Error('CloudCCOpenAPI: Cookie 会话仅支持浏览器环境');
465
+ }
466
+ };
467
+
468
+ CloudCCOpenAPI.prototype._setCookie = function (name, value, maxAgeSeconds) {
469
+ this._requireBrowserCookie();
470
+ document.cookie =
471
+ name +
472
+ '=' +
473
+ encodeURIComponent(value) +
474
+ '; path=/; max-age=' +
475
+ String(maxAgeSeconds) +
476
+ '; SameSite=Lax';
477
+ };
478
+
479
+ CloudCCOpenAPI.prototype._getCookie = function (name) {
480
+ this._requireBrowserCookie();
481
+ var key = name + '=';
482
+ var parts = document.cookie ? document.cookie.split('; ') : [];
483
+ for (var i = 0; i < parts.length; i += 1) {
484
+ if (parts[i].indexOf(key) === 0) return decodeURIComponent(parts[i].slice(key.length));
485
+ }
486
+ return '';
487
+ };
488
+
489
+ /**
490
+ * 将当前会话写入 Cookie
491
+ * @param {Object} [opts]
492
+ * @param {string} [opts.cookieKey='cloudcc_openapi_session']
493
+ * @param {number} [opts.ttlMs=7200000] 默认 2 小时
494
+ */
495
+ CloudCCOpenAPI.prototype.saveSessionToCookie = function (opts) {
496
+ opts = opts || {};
497
+ this._ensureSession();
498
+ var cookieKey = opts.cookieKey || 'cloudcc_openapi_session';
499
+ var ttlMs = Number(opts.ttlMs || 2 * 60 * 60 * 1000);
500
+ if (!Number.isFinite(ttlMs) || ttlMs <= 0) {
501
+ throw new Error('CloudCCOpenAPI: ttlMs 必须为正数');
502
+ }
503
+ var payload = {
504
+ accessToken: this.accessToken,
505
+ baseUrl: this.baseUrl,
506
+ gatewayUrl: this.gatewayUrl || '',
507
+ apiSvcUrl: this.apiSvcUrl || '',
508
+ expireAt: Date.now() + ttlMs
509
+ };
510
+ this._setCookie(cookieKey, JSON.stringify(payload), Math.floor(ttlMs / 1000));
511
+ return payload;
512
+ };
513
+
514
+ /**
515
+ * 清理 Cookie 会话
516
+ * @param {Object} [opts]
517
+ * @param {string} [opts.cookieKey='cloudcc_openapi_session']
518
+ */
519
+ CloudCCOpenAPI.prototype.clearSessionCookie = function (opts) {
520
+ opts = opts || {};
521
+ var cookieKey = opts.cookieKey || 'cloudcc_openapi_session';
522
+ this._setCookie(cookieKey, '', 0);
523
+ };
524
+
525
+ /**
526
+ * 从 Cookie 恢复会话(可选校验 token)
527
+ * @param {Object} [opts]
528
+ * @param {string} [opts.cookieKey='cloudcc_openapi_session']
529
+ * @param {boolean} [opts.validate=false] 是否调用 isValidWithBinding 校验 token
530
+ * @returns {Promise<null|Object>} 成功返回会话数据,失败返回 null
531
+ */
532
+ CloudCCOpenAPI.prototype.restoreSessionFromCookie = async function (opts) {
533
+ opts = opts || {};
534
+ var cookieKey = opts.cookieKey || 'cloudcc_openapi_session';
535
+ var validate = opts.validate === true;
536
+ var raw = this._getCookie(cookieKey);
537
+ if (!raw) return null;
538
+ var session;
539
+ try {
540
+ session = JSON.parse(raw);
541
+ } catch (_e) {
542
+ this.clearSessionCookie({ cookieKey: cookieKey });
543
+ return null;
544
+ }
545
+ if (!session || !session.accessToken || !session.baseUrl || !session.expireAt) {
546
+ this.clearSessionCookie({ cookieKey: cookieKey });
547
+ return null;
548
+ }
549
+ if (Date.now() >= Number(session.expireAt)) {
550
+ this.clearSessionCookie({ cookieKey: cookieKey });
551
+ return null;
552
+ }
553
+ this.accessToken = session.accessToken;
554
+ this.baseUrl = trimUrl(session.baseUrl);
555
+ this.gatewayUrl = session.gatewayUrl || '';
556
+ this.apiSvcUrl = session.apiSvcUrl || '';
557
+ if (validate) {
558
+ try {
559
+ var v = await this.isValidWithBinding();
560
+ if (!v || v.returnCode !== '1') {
561
+ this.clearSessionCookie({ cookieKey: cookieKey });
562
+ this.accessToken = '';
563
+ return null;
564
+ }
565
+ } catch (_e2) {
566
+ this.clearSessionCookie({ cookieKey: cookieKey });
567
+ this.accessToken = '';
568
+ return null;
569
+ }
570
+ }
571
+ return session;
572
+ };
573
+
574
+ CloudCCOpenAPI.prototype._headersJson = function () {
575
+ return {
576
+ 'Content-Type': 'application/json; charset=UTF-8',
577
+ accessToken: this.accessToken
578
+ };
579
+ };
580
+
581
+ CloudCCOpenAPI.prototype._postJson = async function (path, body) {
582
+ this._ensureSession();
583
+ var url = this.baseUrl + path;
584
+ var res = await this._fetch(url, {
585
+ method: 'POST',
586
+ headers: this._headersJson(),
587
+ body: JSON.stringify(body)
588
+ });
589
+ var text = await res.text();
590
+ var data = null;
591
+ try {
592
+ data = text ? JSON.parse(text) : null;
593
+ } catch (e) {
594
+ var errParse = new Error('CloudCCOpenAPI: 响应非 JSON');
595
+ errParse.cause = e;
596
+ errParse.raw = text;
597
+ errParse.status = res.status;
598
+ throw errParse;
599
+ }
600
+ if (!res.ok) {
601
+ var errHttp = new Error(data && data.returnInfo ? data.returnInfo : 'HTTP ' + res.status);
602
+ errHttp.status = res.status;
603
+ errHttp.payload = data;
604
+ throw errHttp;
605
+ }
606
+ return data;
607
+ };
608
+
609
+ CloudCCOpenAPI.prototype._postJsonWithConfig = async function (url, body, config) {
610
+ this._ensureSession();
611
+ config = config || {};
612
+ var timeout = Number(config.timeout);
613
+ var hasTimeout = Number.isFinite(timeout) && timeout > 0;
614
+ var controller = hasTimeout && typeof AbortController !== 'undefined' ? new AbortController() : null;
615
+ var timer = null;
616
+ if (controller) {
617
+ timer = setTimeout(function () {
618
+ controller.abort();
619
+ }, timeout);
620
+ }
621
+ try {
622
+ var requestInit = {
623
+ method: 'POST',
624
+ headers: this._headersJson(),
625
+ body: JSON.stringify(body)
626
+ };
627
+ if (controller) requestInit.signal = controller.signal;
628
+ var res = await this._fetch(url, requestInit);
629
+ var text = await res.text();
630
+ var data = null;
631
+ try {
632
+ data = text ? JSON.parse(text) : null;
633
+ } catch (e) {
634
+ var errParse = new Error('CloudCCOpenAPI: 响应非 JSON');
635
+ errParse.cause = e;
636
+ errParse.raw = text;
637
+ errParse.status = res.status;
638
+ throw errParse;
639
+ }
640
+ if (!res.ok) {
641
+ var errHttp = new Error(data && data.returnInfo ? data.returnInfo : 'HTTP ' + res.status);
642
+ errHttp.status = res.status;
643
+ errHttp.payload = data;
644
+ throw errHttp;
645
+ }
646
+ return data;
647
+ } catch (e2) {
648
+ if (e2 && e2.name === 'AbortError') {
649
+ var errTimeout = new Error('CloudCCOpenAPI: 请求超时');
650
+ errTimeout.code = 'ETIMEDOUT';
651
+ errTimeout.timeout = timeout;
652
+ throw errTimeout;
653
+ }
654
+ throw e2;
655
+ } finally {
656
+ if (timer) clearTimeout(timer);
657
+ }
658
+ };
659
+
660
+ /**
661
+ * 通用调用:自行传 serviceName 及文档要求的字段
662
+ * @param {Record<string, *>} payload
663
+ */
664
+ CloudCCOpenAPI.prototype.common = function (payload) {
665
+ return this._postJson('/openApi/common', payload);
666
+ };
667
+
668
+ /**
669
+ * 请求 common 自定义类接口
670
+ * @param {string} className 类名
671
+ * @param {string} methodName 方法名
672
+ * @param {Array} params 参数集合
673
+ * @param {object} [config] http 配置项,例如:{ timeout: 1000 }
674
+ * @returns {Promise<*>}
675
+ */
676
+ CloudCCOpenAPI.prototype.post = function (className, methodName, params, config) {
677
+ if (!className) {
678
+ return Promise.reject(new Error('CloudCCOpenAPI: className 为必填'));
679
+ }
680
+ if (!methodName) {
681
+ return Promise.reject(new Error('CloudCCOpenAPI: methodName 为必填'));
682
+ }
683
+ if (!this.apiSvcUrl) {
684
+ return Promise.reject(new Error('CloudCCOpenAPI: 缺少 apiSvcUrl,请先调用 login(username, password)'));
685
+ }
686
+ var url = trimUrl(this.apiSvcUrl) + '/api/openCall/common';
687
+ return this._postJsonWithConfig(
688
+ url,
689
+ {
690
+ className: className,
691
+ methodName: methodName,
692
+ params: params instanceof Array ? params : []
693
+ },
694
+ config
695
+ );
696
+ };
697
+
698
+ // ---------- 2.2 accessToken ----------
699
+ CloudCCOpenAPI.prototype.isValidWithBinding = function () {
700
+ return this.common({ serviceName: 'isValidWithBinding' });
701
+ };
702
+
703
+ // ---------- 2.3 查询 ----------
704
+ CloudCCOpenAPI.prototype.cquery = function (params) {
705
+ return this.common(
706
+ Object.assign({ serviceName: 'cquery' }, params)
707
+ );
708
+ };
709
+
710
+ CloudCCOpenAPI.prototype.cqueryWithRoleRight = function (params) {
711
+ return this.common(
712
+ Object.assign({ serviceName: 'cqueryWithRoleRight' }, params)
713
+ );
714
+ };
715
+
716
+ CloudCCOpenAPI.prototype.pageQuery = function (params) {
717
+ return this.common(
718
+ Object.assign({ serviceName: 'pageQuery' }, params)
719
+ );
720
+ };
721
+
722
+ CloudCCOpenAPI.prototype.pageQueryWithRoleRight = function (params) {
723
+ return this.common(
724
+ Object.assign({ serviceName: 'pageQueryWithRoleRight' }, params)
725
+ );
726
+ };
727
+
728
+ CloudCCOpenAPI.prototype.getQueryPermisson = function (params) {
729
+ return this.common(
730
+ Object.assign({ serviceName: 'getQueryPermisson' }, params)
731
+ );
732
+ };
733
+
734
+ CloudCCOpenAPI.prototype.cqlQueryWithLogInfo = function (params) {
735
+ return this.common(
736
+ Object.assign({ serviceName: 'cqlQueryWithLogInfo' }, params)
737
+ );
738
+ };
739
+
740
+ CloudCCOpenAPI.prototype.cqlQueryWithStatic = function (params) {
741
+ return this.common(
742
+ Object.assign({ serviceName: 'cqlQueryWithStatic' }, params)
743
+ );
744
+ };
745
+
746
+ // ---------- 2.4–2.7 增删改 upsert ----------
747
+ CloudCCOpenAPI.prototype.insert = function (params) {
748
+ var p = Object.assign({ serviceName: 'insert' }, params);
749
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
750
+ return this.common(p);
751
+ };
752
+
753
+ CloudCCOpenAPI.prototype.insertWithRoleRight = function (params) {
754
+ var p = Object.assign({ serviceName: 'insertWithRoleRight' }, params);
755
+ if (p.Data !== undefined) p.Data = stringifyDataIfNeeded(p.Data);
756
+ else if (p.data !== undefined) p.Data = stringifyDataIfNeeded(p.data);
757
+ delete p.data;
758
+ return this.common(p);
759
+ };
760
+
761
+ CloudCCOpenAPI.prototype.deleteRecords = function (params) {
762
+ var p = Object.assign({ serviceName: 'delete' }, params);
763
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
764
+ return this.common(p);
765
+ };
766
+
767
+ CloudCCOpenAPI.prototype.deleteWithRoleRight = function (params) {
768
+ var p = Object.assign({ serviceName: 'deleteWithRoleRight' }, params);
769
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
770
+ return this.common(p);
771
+ };
772
+
773
+ CloudCCOpenAPI.prototype.update = function (params) {
774
+ var p = Object.assign({ serviceName: 'update' }, params);
775
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
776
+ return this.common(p);
777
+ };
778
+
779
+ CloudCCOpenAPI.prototype.updateWithRoleRight = function (params) {
780
+ var p = Object.assign({ serviceName: 'updateWithRoleRight' }, params);
781
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
782
+ return this.common(p);
783
+ };
784
+
785
+ CloudCCOpenAPI.prototype.upsert = function (params) {
786
+ var p = Object.assign({ serviceName: 'upsert' }, params);
787
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
788
+ return this.common(p);
789
+ };
790
+
791
+ CloudCCOpenAPI.prototype.upsertWithRoleRight = function (params) {
792
+ var p = Object.assign({ serviceName: 'upsertWithRoleRight' }, params);
793
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
794
+ return this.common(p);
795
+ };
796
+
797
+ // ---------- 2.8 自助 Mongo ----------
798
+ CloudCCOpenAPI.prototype.customService = function (params) {
799
+ var p = Object.assign({ serviceName: 'customService' }, params);
800
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
801
+ return this.common(p);
802
+ };
803
+
804
+ // ---------- 2.9 短信 ----------
805
+ CloudCCOpenAPI.prototype.telMessage = function (params) {
806
+ var p = Object.assign({ serviceName: 'telMessage' }, params);
807
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
808
+ return this.common(p);
809
+ };
810
+
811
+ // ---------- 2.10 图片(JSON 通道) ----------
812
+ CloudCCOpenAPI.prototype.uploadImg = function (params) {
813
+ var p = Object.assign({ serviceName: 'uploadImg' }, params);
814
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
815
+ return this._postJson('/openApi/file', p);
816
+ };
817
+
818
+ CloudCCOpenAPI.prototype.uploadImgMany = function (params) {
819
+ var p = Object.assign({ serviceName: 'uploadImgMany' }, params);
820
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
821
+ return this._postJson('/openApi/file', p);
822
+ };
823
+
824
+ CloudCCOpenAPI.prototype.getImgProperty = function (params) {
825
+ var p = Object.assign({ serviceName: 'getImgProperty' }, params);
826
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
827
+ return this.common(p);
828
+ };
829
+
830
+ // ---------- 2.12 base64 附件 ----------
831
+ CloudCCOpenAPI.prototype.uploadAttachement = function (params) {
832
+ return this.common(
833
+ Object.assign({ serviceName: 'uploadAttachement' }, params)
834
+ );
835
+ };
836
+
837
+ CloudCCOpenAPI.prototype.downloadAttachement = function (params) {
838
+ return this.common(
839
+ Object.assign({ serviceName: 'downloadAttachement' }, params)
840
+ );
841
+ };
842
+
843
+ CloudCCOpenAPI.prototype.deleteAttachment = function (params) {
844
+ return this.common(
845
+ Object.assign({ serviceName: 'deleteAttachment' }, params)
846
+ );
847
+ };
848
+
849
+ CloudCCOpenAPI.prototype.deleteFile = function (params) {
850
+ return this.common(
851
+ Object.assign({ serviceName: 'deleteFile' }, params)
852
+ );
853
+ };
854
+
855
+ // ---------- 2.17 邮件 ----------
856
+ CloudCCOpenAPI.prototype.sendEmail = function (params) {
857
+ var p = Object.assign({ serviceName: 'sendEmail' }, params);
858
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
859
+ return this.common(p);
860
+ };
861
+
862
+ // ---------- 2.18 Chatter(统一走 common,附带便捷方法) ----------
863
+ CloudCCOpenAPI.prototype.chatter = function (serviceName, data) {
864
+ var payload = { serviceName: serviceName };
865
+ if (data !== undefined) payload.data = stringifyDataIfNeeded(data);
866
+ return this.common(payload);
867
+ };
868
+
869
+ CloudCCOpenAPI.prototype.getChatters01 = function (data) {
870
+ return this.chatter('getChatters01', data);
871
+ };
872
+
873
+ CloudCCOpenAPI.prototype.addMicroComment = function (data) {
874
+ return this.chatter('addMicroComment', data);
875
+ };
876
+
877
+ // ---------- 2.19–2.21 ----------
878
+ CloudCCOpenAPI.prototype.getPickListValue = function (params) {
879
+ var p = Object.assign({ serviceName: 'getPickListValue' }, params);
880
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
881
+ return this.common(p);
882
+ };
883
+
884
+ CloudCCOpenAPI.prototype.saveDependency = function (params) {
885
+ var p = Object.assign({ serviceName: 'saveDependency' }, params);
886
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
887
+ return this.common(p);
888
+ };
889
+
890
+ CloudCCOpenAPI.prototype.getApprovalPaddingList = function (params) {
891
+ return this.common(
892
+ Object.assign({ serviceName: 'getApprovalPaddingList' }, params)
893
+ );
894
+ };
895
+
896
+ CloudCCOpenAPI.prototype.doApproved = function (params) {
897
+ var p = Object.assign({ serviceName: 'doApproved' }, params);
898
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
899
+ return this.common(p);
900
+ };
901
+
902
+ CloudCCOpenAPI.prototype.doRejected = function (params) {
903
+ var p = Object.assign({ serviceName: 'doRejected' }, params);
904
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
905
+ return this.common(p);
906
+ };
907
+
908
+ CloudCCOpenAPI.prototype.doReassign = function (params) {
909
+ var p = Object.assign({ serviceName: 'doReassign' }, params);
910
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
911
+ return this.common(p);
912
+ };
913
+
914
+ CloudCCOpenAPI.prototype.reCall = function (params) {
915
+ var p = Object.assign({ serviceName: 'reCall' }, params);
916
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
917
+ return this.common(p);
918
+ };
919
+
920
+ CloudCCOpenAPI.prototype.submitForApproval = function (params) {
921
+ var p = Object.assign({ serviceName: 'submitForApproval' }, params);
922
+ if (p.data !== undefined) p.data = stringifyDataIfNeeded(p.data);
923
+ return this.common(p);
924
+ };
925
+
926
+ // ---------- 2.22–2.25 应用 / 选项卡 / 搜索 ----------
927
+ CloudCCOpenAPI.prototype.getAppList = function (params) {
928
+ return this.common(
929
+ Object.assign({ serviceName: 'getAppList' }, params || {})
930
+ );
931
+ };
932
+
933
+ CloudCCOpenAPI.prototype.getAllTabs = function (params) {
934
+ return this.common(
935
+ Object.assign({ serviceName: 'getAllTabs' }, params || {})
936
+ );
937
+ };
938
+
939
+ CloudCCOpenAPI.prototype.getAppAndTabList = function (params) {
940
+ return this.common(
941
+ Object.assign({ serviceName: 'getAppAndTabList' }, params || {})
942
+ );
943
+ };
944
+
945
+ CloudCCOpenAPI.prototype.getMySetupObjs = function (params) {
946
+ return this.common(
947
+ Object.assign({ serviceName: 'getMySetupObjs' }, params || {})
948
+ );
949
+ };
950
+
951
+ // ---------- 2.26 用户 ----------
952
+ CloudCCOpenAPI.prototype.searchRole = function (params) {
953
+ return this.common(
954
+ Object.assign({ serviceName: 'searchRole' }, params || {})
955
+ );
956
+ };
957
+
958
+ CloudCCOpenAPI.prototype.searchProfile = function (params) {
959
+ return this.common(
960
+ Object.assign({ serviceName: 'searchProfile' }, params || {})
961
+ );
962
+ };
963
+
964
+ CloudCCOpenAPI.prototype.createUser = function (params) {
965
+ return this.common(
966
+ Object.assign({ serviceName: 'createUser' }, params || {})
967
+ );
968
+ };
969
+
970
+ /**
971
+ * 文件流上传(multipart/form-data)
972
+ * @param {FormData} formData 需含 serviceName、relatedId、fileName、suffix 及文件字段(与官方示例一致)
973
+ */
974
+ CloudCCOpenAPI.prototype.uploadFileFormData = async function (formData) {
975
+ this._ensureSession();
976
+ var url = this.baseUrl + '/openApi/file';
977
+ var res = await this._fetch(url, {
978
+ method: 'POST',
979
+ headers: { accessToken: this.accessToken },
980
+ body: formData
981
+ });
982
+ var text = await res.text();
983
+ var data = null;
984
+ try {
985
+ data = text ? JSON.parse(text) : null;
986
+ } catch (e) {
987
+ var errParse = new Error('CloudCCOpenAPI: 响应非 JSON');
988
+ errParse.raw = text;
989
+ errParse.status = res.status;
990
+ throw errParse;
991
+ }
992
+ if (!res.ok) {
993
+ var errHttp = new Error(data && data.returnInfo ? data.returnInfo : 'HTTP ' + res.status);
994
+ errHttp.status = res.status;
995
+ errHttp.payload = data;
996
+ throw errHttp;
997
+ }
998
+ return data;
999
+ };
1000
+
1001
+ /**
1002
+ * 文件下载(二进制流,GET)
1003
+ * @param {string} fileId
1004
+ * @returns {Promise<Blob>}
1005
+ */
1006
+ CloudCCOpenAPI.prototype.downloadFileBlob = async function (fileId) {
1007
+ this._ensureSession();
1008
+ var q = new URLSearchParams({
1009
+ accessToken: this.accessToken,
1010
+ id: fileId
1011
+ });
1012
+ var url = this.baseUrl + '/openApi/downloadFile?' + q.toString();
1013
+ var res = await this._fetch(url, { method: 'GET' });
1014
+ if (!res.ok) {
1015
+ var errHttp = new Error('HTTP ' + res.status);
1016
+ errHttp.status = res.status;
1017
+ throw errHttp;
1018
+ }
1019
+ return res.blob();
1020
+ };
1021
+
1022
+ /**
1023
+ * Chatter 文件下载(文档为 POST /openApi/common,返回二进制流,不用 JSON 解析)
1024
+ * @param {string} fileId 文件所在记录相关 id(见官方说明)
1025
+ * @returns {Promise<Blob>}
1026
+ */
1027
+ CloudCCOpenAPI.prototype.downloadFileChatterBlob = async function (fileId) {
1028
+ this._ensureSession();
1029
+ var url = this.baseUrl + '/openApi/common';
1030
+ var res = await this._fetch(url, {
1031
+ method: 'POST',
1032
+ headers: this._headersJson(),
1033
+ body: JSON.stringify({
1034
+ serviceName: 'downloadFileChatter',
1035
+ fileId: fileId
1036
+ })
1037
+ });
1038
+ if (!res.ok) {
1039
+ var err = new Error('HTTP ' + res.status);
1040
+ err.status = res.status;
1041
+ throw err;
1042
+ }
1043
+ var ct = (res.headers && res.headers.get && res.headers.get('content-type')) || '';
1044
+ if (ct.indexOf('application/json') !== -1) {
1045
+ var text = await res.text();
1046
+ try {
1047
+ return JSON.parse(text);
1048
+ } catch (e) {
1049
+ return text;
1050
+ }
1051
+ }
1052
+ return res.blob();
1053
+ };
1054
+
1055
+ /**
1056
+ * 用户头像展示(GET,请求头 accessToken)
1057
+ * @param {string} [userId] 不传则默认当前登录人
1058
+ * @returns {Promise<Blob>}
1059
+ */
1060
+ CloudCCOpenAPI.prototype.userPhotoBlob = async function (userId) {
1061
+ this._ensureSession();
1062
+ var q = userId ? '?id=' + encodeURIComponent(userId) : '';
1063
+ var url = this.baseUrl + '/api/user/userPhoto' + q;
1064
+ var res = await this._fetch(url, {
1065
+ method: 'GET',
1066
+ headers: { accessToken: this.accessToken }
1067
+ });
1068
+ if (!res.ok) {
1069
+ var err = new Error('HTTP ' + res.status);
1070
+ err.status = res.status;
1071
+ throw err;
1072
+ }
1073
+ return res.blob();
1074
+ };
1075
+
1076
+ CloudCCOpenAPI.VERSION = '1.3.0';
1077
+ CloudCCOpenAPI.AccountPasswordLogin = AccountPasswordLogin;
1078
+ CloudCCOpenAPI.DEFAULT_LOGIN_SVC_BASE = DEFAULT_LOGIN_SVC_BASE;
1079
+
1080
+ return {
1081
+ CloudCCOpenAPI: CloudCCOpenAPI,
1082
+ AccountPasswordLogin: AccountPasswordLogin,
1083
+ DEFAULT_LOGIN_SVC_BASE: DEFAULT_LOGIN_SVC_BASE
1084
+ };
1085
+ });