UNPKG

@cloudbase/lowcode-deployer

Version:

deploy weda app

346 lines (345 loc) 13.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TCBAPICloudApiService = exports.LocalStorage = void 0; const request = require('request'); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); function isObject(x) { return typeof x === 'object' && !Array.isArray(x) && x !== null; } // 移除对象中的空值,防止调用云 API 失败 function deepRemoveVoid(obj) { if (Array.isArray(obj)) { return obj.map(deepRemoveVoid); } else if (isObject(obj)) { let result = {}; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = obj[key]; if (typeof value !== 'undefined' && value !== null) { result[key] = deepRemoveVoid(value); } } } return result; } else { return obj; } } function genSeqId() { return Math.random().toString(16).slice(2); } class CommonError extends Error { constructor(message, code = '-1', requestId = '', originData = undefined) { if (typeof message === 'object') { message.code = code; message.requestId = requestId; message.originData = originData; return message; } else { super(message); this.code = code; this.requestId = requestId; this.originData = originData; } } toString() { return `[${this.code}] ${this.message} requestId:${this.requestId || ''}`; } toLocaleString() { return `[${this.code}] ${this.message} requestId:${this.requestId || ''}`; } toJSON() { return { code: this.code, message: this.message, requestId: this.requestId, }; } } class LocalStorage { constructor(projectPath) { this._map = new Map(); if (projectPath) { this._path = path_1.default.join(projectPath, '.storage.json'); } if (this._path && fs_extra_1.default.existsSync(this._path)) { try { const json = fs_extra_1.default.readJSONSync(this._path); for (const key in json) { this._map.set(key, json[key]); } } catch (e) { } } } getItem(key) { return this._map.get(key); } setItem(key, value) { this._map.set(key, value); try { if (this._path) { fs_extra_1.default.writeJson(this._path, Object.fromEntries(this._map)); } } catch (e) { } } removeItem(key) { this._map.delete(key); try { if (this._path) { fs_extra_1.default.writeJson(this._path, Object.fromEntries(this._map)); } } catch (e) { } } } exports.LocalStorage = LocalStorage; class TCBAPICloudApiService { constructor(options) { const { env, service, version, apiOrigin, timeout = 60000, endpoint = '', uin, username, password, localstorage, packRes, } = options; this._CREDENTIAL_KEY = `credentials_${env}`; this._env = env; this._serviceType = service; this._version = version; this._refreshTokenPromise = null; this._uin = uin; this._username = username; this._password = password; this._localstorage = localstorage || new LocalStorage(); this._packRes = packRes || function (res) { var _a; return (_a = res.data) === null || _a === void 0 ? void 0 : _a.Response; }; if ((process.env.IDAAS_ENDPOINT && !this._uin) || (!process.env.IDAAS_ENDPOINT && (!this._username || !this._password))) { throw new Error('invalid credential'); } const host = apiOrigin; let protocol = 'http://'; let httpEndpoint = host; const headers = { origin: 'http://127.0.0.1', referer: 'http://127.0.0.1', }; if (endpoint) { const url = new URL(endpoint); protocol = `${url.protocol}//`; httpEndpoint = url.host; if (host) { headers.host = host; } } this._httpProfile = { protocol, httpEndpoint, url: `${protocol}${httpEndpoint}`, timeout, headers, }; } async request(action, data = {}) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; const { access_token } = await this._getCredentials(); const reqData = deepRemoveVoid({ ...data }); try { const res = await this.doReqeust({ url: `${(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.url}/capi?env=${this._env}`, method: 'post', headers: { 'Content-Type': 'application/json;charset=UTF-8' }, body: { env: this._env, access_token: access_token, serviceType: this._serviceType, action, version: this._version, data: reqData, }, }, { debug: true }); return this._packRes(res); } catch (e) { if ((_e = (_d = (_c = (_b = e.originData) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.Response) === null || _d === void 0 ? void 0 : _d.Error) === null || _e === void 0 ? void 0 : _e.ReqeustId) { e.requestId = (_j = (_h = (_g = (_f = e.originData) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.Response) === null || _h === void 0 ? void 0 : _h.Error) === null || _j === void 0 ? void 0 : _j.ReqeustId; } throw e; } } async doReqeust({ url, headers: _headers = {}, body = {}, method = 'post' }, options) { var _a; const headers = { ...(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.headers, ..._headers }; let seqId; for (const key in headers) { if (key.toLowerCase() === 'x-seqid') { seqId = headers[key]; break; } } if (!seqId) { seqId = genSeqId(); headers['x-seqid'] = seqId; } return new Promise((resolve, reject) => { var _a; request({ url, method, headers, body, timeout: (_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.timeout, json: true, strictSSL: false, }, function (err, res, data) { if (err) { reject(new CommonError(err)); } else if (res.statusCode >= 300) { let message; try { message = data.message || res.statusCode; } catch (e) { } reject(new CommonError(`${url} 请求响应状态异常 ${message}`, res.statusCode, seqId, data)); } else if (data.code) { reject(new CommonError(data.message, data.code, seqId, data)); } else { resolve(data); } }); }); } _isExpired(credentials) { if (credentials) { if (!credentials.expires_at || new Date(credentials.expires_at).getTime() < Date.now()) { return true; } return false; } return true; } async _getCredentials() { var _a, _b, _c, _d, _e, _f, _g, _h; const cache = this._localstorage.getItem(this._CREDENTIAL_KEY); if (!this._isExpired(cache)) { return cache; } if (cache === null || cache === void 0 ? void 0 : cache.refresh_token) { return this._refreshToken(cache.refresh_token); } const seqId = genSeqId(); let error; try { let res; if (process.env.IDAAS_ENDPOINT) { res = await this.doReqeust({ url: `${process.env.IDAAS_ENDPOINT}/cloudbase.auth.v2.MgrV2/DescribeAdministratorToken`, method: 'post', headers: { ['x-request-id']: seqId, ['x-seqid']: seqId, }, body: { RequestId: seqId, Uin: this._uin, AppId: 1, SubAccountUin: this._uin, Region: process.env.PRIVATE_CLOUD_API_REGION || 'chongqing', EnvId: this._env, }, }, { debug: true }); if ((_a = res.Response) === null || _a === void 0 ? void 0 : _a.Error) { throw new CommonError(`DescribeAdministratorToken 请求响应状态异常 ${res.Response.Error.Message}`, (_b = res.Response.Error) === null || _b === void 0 ? void 0 : _b.Code, seqId, res); } const { TokenType, AccessToken, RefreshToken, ExpiresIn } = res.Response || {}; res = { token_type: TokenType, access_token: AccessToken, refresh_token: RefreshToken, expires_in: ExpiresIn, }; } else { res = await this.doReqeust({ url: `${((_c = this._httpProfile) === null || _c === void 0 ? void 0 : _c.protocol) && ((_d = this._httpProfile.headers) === null || _d === void 0 ? void 0 : _d.host) ? `${(_e = this._httpProfile) === null || _e === void 0 ? void 0 : _e.protocol}${(_f = this._httpProfile.headers) === null || _f === void 0 ? void 0 : _f.host}` : (_g = this._httpProfile) === null || _g === void 0 ? void 0 : _g.url}/auth/v1/signin?clientId=${this._env}`, method: 'post', headers: { ['x-request-id']: seqId, ['x-seqid']: seqId, }, body: { username: this._username, password: this._password, isEncrypt: true }, }, { debug: true }); if (res === null || res === void 0 ? void 0 : res.error) { throw new CommonError(res.error_description, res.error, seqId, res); } } this._setCredentials(res); return res; } catch (e) { if ((_h = e.originData) === null || _h === void 0 ? void 0 : _h.error) { error = e.originData; } else { this._setCredentials(null); throw e; } } if (error === null || error === void 0 ? void 0 : error.error) { this._setCredentials(null); throw new CommonError(`/auth/v1/signin ${error.error_description}`, error.error || 'unreachable', error.requestId || seqId, error); } } _setCredentials(credential) { if (!credential) { this._localstorage.removeItem(this._CREDENTIAL_KEY); return; } if (!credential.expires_at && credential.expires_in) { credential.expires_at = Date.now() + credential.expires_in * 1000; } this._localstorage.setItem(this._CREDENTIAL_KEY, credential); } async _refreshToken(refreshToken) { var _a; const seqId = genSeqId(); if (!this._refreshTokenPromise) { this._refreshTokenPromise = this.doReqeust({ url: `${(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.url}/auth/v1/token`, headers: { ['x-request-id']: seqId, ['x-seqid']: seqId }, body: { client_id: this._env, grant_type: 'refresh_token', refresh_token: refreshToken, }, }).then((res) => { this._refreshTokenPromise = null; return res; }, (e) => { this._refreshTokenPromise = null; this._setCredentials(null); throw e; }); } const res = await this._refreshTokenPromise; if (res.error) { this._setCredentials(null); throw new CommonError(`/auth/v1/token ${res.error_description}`, res.error || 'unreachable', res.requestId || seqId, res); } this._setCredentials(res); return res; } } exports.TCBAPICloudApiService = TCBAPICloudApiService;