UNPKG

@lastos/page-spy-plugin-mp-data-harbor

Version:
351 lines (338 loc) 9.79 kB
import { psLog as psLog$1 } from '@lastos/page-spy-mp-base'; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _defineProperty(obj, key, value) { key = toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const unproxyConsole = { ...console }; const psLog = ['log', 'info', 'error', 'warn', 'debug'].reduce((result, method) => { result[method] = function () { for (var _len = arguments.length, message = new Array(_len), _key = 0; _key < _len; _key++) { message[_key] = arguments[_key]; } console[method]("[PageSpy] [".concat(method.toLocaleUpperCase(), "] "), ...message); }; result.unproxy[method] = function () { for (var _len2 = arguments.length, message = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { message[_key2] = arguments[_key2]; } unproxyConsole[method]("[PageSpy] [".concat(method.toLocaleUpperCase(), "] "), ...message); }; return result; }, { unproxy: {} }); const removeEndSlash = s => { return s.replace(/\/$/, ''); }; class MemoryHarbor { constructor() { _defineProperty(this, "container", []); } add(data) { this.container.push(data); return true; } clear() { this.container = []; } } const ROOM_SESSION_KEY = 'page-spy-room'; // the plugin should store the mp sdk by self, received from initiation. let mp; const getMPSDK = () => mp; const setMPSDK = sdk => { mp = sdk; }; const getDeviceId = () => { const cache = mp.getStorageSync(ROOM_SESSION_KEY); if (cache !== null && cache !== void 0 && cache.address && typeof cache.address === 'string') { return cache.address.slice(0, 4); } return '--'; }; const formatFilename = name => { return name.toString().replace(/[^\w]/g, '_'); }; const makeData = (type, data) => { return { type, timestamp: Date.now(), data }; }; const buildSearchParams = obj => { return Object.entries(obj).map(_ref => { let [key, value] = _ref; return "".concat(key, "=").concat(encodeURIComponent(value)); }).join('&'); }; const saveData = async _ref => { let { url, data } = _ref; return new Promise((resolve, reject) => { const mp = getMPSDK(); mp.request({ data, url, method: 'POST', success: res => { if (res.statusCode === 200) { const data = res.data; if (data.success) { resolve(data); } else { reject(data); } } }, fail: err => { psLog.warn('Upload failed', err); reject(err); } }); }); }; const defaultConfig = { caredData: { console: true, network: true, storage: true, system: true, meta: true }, filename: () => { return new Date().toLocaleString(); }, onAfterUpload: () => {} }; class MPDataHarborPlugin { constructor(config) { _defineProperty(this, "enforce", 'pre'); _defineProperty(this, "name", 'DataHarborPlugin'); _defineProperty(this, "apiBase", ''); _defineProperty(this, "isPaused", false); _defineProperty(this, "$socketStore", null); _defineProperty(this, "$pageSpyConfig", null); _defineProperty(this, "client", null); this.$harborConfig = { ...defaultConfig, ...config }; this.harbor = new MemoryHarbor(); } async onInit(_ref) { var _this$$socketStore; let { socketStore, config, client, mp } = _ref; if (MPDataHarborPlugin.hasInited) return; MPDataHarborPlugin.hasInited = true; setMPSDK(mp); this.$pageSpyConfig = config; this.$socketStore = socketStore; // TODO: fix this type issue this.client = client; const { api, enableSSL, offline } = config; if (!offline && !api) { psLog$1.warn("Cannot upload log to PageSpy for miss 'api' configuration. See: ", config); } else { // because this plugin is mainly used in mp, so align with mp sdk, default to https const apiScheme = enableSSL === false ? 'http://' : 'https://'; this.apiBase = removeEndSlash("".concat(apiScheme).concat(api)); } (_this$$socketStore = this.$socketStore) === null || _this$$socketStore === void 0 || _this$$socketStore.addListener('public-data', message => { if (this.isPaused || !this.isCaredPublicData(message)) return; const data = makeData(message.type, message.data); const ok = this.harbor.add(data); if (!ok) { psLog$1.warn("[".concat(this.name, "] Fail to save data in harbor "), data); } }); } onActionSheet() { return [{ text: '上传离线日志', action: async () => { const mp = getMPSDK(); mp.showLoading({ title: '正在上传离线日志...' }); try { const result = await this.upload(); mp.hideLoading(); if (result) { this.$harborConfig.onAfterUpload(result); mp.showModal({ title: '上传成功', confirmText: '复制链接', showCancel: false, success(res) { if (res.confirm) { mp.setClipboardData({ data: result }); } } }); } else { mp.showToast({ title: '上传失败' }); } } catch (e) { mp.hideLoading(); mp.showToast({ title: '上传失败' }); } } }]; } async upload(params) { var _this$client; const { filename } = this.$harborConfig; const { project = '', title = '' } = this.$pageSpyConfig || {}; const tags = { project, title, deviceId: getDeviceId(), // userAgent: navigator.userAgent, userAgent: (_this$client = this.client) === null || _this$client === void 0 ? void 0 : _this$client.getName(), remark: (params === null || params === void 0 ? void 0 : params.remark) || '', name: formatFilename(filename()) + '.json' }; const data = [...this.harbor.container]; data.push(this.makeMetaInfo()); const url = "".concat(this.apiBase, "/api/v1/jsonLog/upload?").concat(buildSearchParams(tags)); let debugUrl = ''; try { const res = await saveData({ data, url }); debugUrl = this.getDebugUrl(res); if ((params === null || params === void 0 ? void 0 : params.clearCache) !== false) { var _this$$socketStore2; this.harbor.clear(); (_this$$socketStore2 = this.$socketStore) === null || _this$$socketStore2 === void 0 || _this$$socketStore2.dispatchEvent('harbor-clear', null); } } catch (e) { psLog$1.error(e); } return debugUrl; } onReset() { this.harbor.clear(); MPDataHarborPlugin.hasInited = false; } pause() { this.isPaused = true; } resume() { this.isPaused = false; } // Drop data in harbor and re-record reharbor() { var _this$$socketStore3; this.harbor.clear(); (_this$$socketStore3 = this.$socketStore) === null || _this$$socketStore3 === void 0 || _this$$socketStore3.dispatchEvent('harbor-clear', null); if (this.isPaused) { this.isPaused = false; } } isCaredPublicData(message) { if (!message) return false; const { type } = message; const { caredData } = this.$harborConfig; switch (type) { case 'console': if (caredData.console) return true; return false; case 'storage': if (caredData.storage) return true; return false; case 'system': if (caredData.system) return true; return false; case 'network': return !!caredData.network; // const { url } = message.data as RequestItem; // const isFetchHarborStockUrl = this.harbor.stock.includes(url); // if (caredData.network && !isFetchHarborStockUrl) return true; // return false; default: return false; } } // To make sure the replay panel can properly display, we must put a client info // message to the data. makeMetaInfo() { var _this$client2; const clientInfo = (_this$client2 = this.client) === null || _this$client2 === void 0 ? void 0 : _this$client2.makeClientInfoMsg(); return { type: 'meta', timestamp: Date.now(), data: clientInfo }; } getDebugUrl(result) { if (!result || !result.success) return ''; const debugOrigin = "".concat(this.apiBase, "/#/replay"); const logUrl = "".concat(this.apiBase, "/api/v1/log/download?fileId=").concat(result.data.fileId); return "".concat(debugOrigin, "?url=").concat(logUrl); } } _defineProperty(MPDataHarborPlugin, "hasInited", false); export { MPDataHarborPlugin as default }; //# sourceMappingURL=index.min.js.map