export function isAbsoluteURL(url: string) { // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed // by any combination of letters, digits, plus, period, or hyphen. return /^([a-z][a-z\d+-.]*:)?\/\//i.test(url); } export function combineURLs(baseURL: string, relativeURL?: string) { return relativeURL ? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}` : baseURL; } export function buildFullPath(baseURL: string, requestedURL: string): string { if (baseURL && !isAbsoluteURL(requestedURL)) { return combineURLs(baseURL, requestedURL); } return requestedURL; } type DeepCopy = T extends object ? T extends Array ? DeepCopy[] : { [K in keyof T]: T[K] extends object ? DeepCopy : T[K] } : T export function deepCopy(obj: T): DeepCopy { let target; if (typeof obj === 'object' && obj !== null) { const isArray = Array.isArray(obj); if (isArray) { target = []; obj.forEach((elem) => target.push(deepCopy(elem))); } else { target = {}; Object.keys(obj).forEach((key) => { target[key] = deepCopy(obj[key]); }); } } else { target = obj; } return target; } export function getType(obj: any): string { const type = typeof obj; if (type !== 'object') return type; return Object.prototype.toString.call(obj) .replace(/^\[object\s+(\S+)\]$/, '$1') .toLowerCase(); } declare const wx: any export function isWxAppEnv() { return typeof wx !== 'undefined' && typeof wx.request === 'function' }