UNPKG

@edgeone/framework-detect

Version:

A framework detection library for web projects

2,046 lines (1,857 loc) 407 kB
import * as fs$1 from 'node:fs'; import * as pathModule from 'node:path'; import require$$1 from 'util'; import stream, { Readable } from 'stream'; import require$$1$1 from 'path'; import require$$3 from 'http'; import require$$4 from 'https'; import require$$0$1 from 'url'; import require$$6 from 'fs'; import require$$8 from 'crypto'; import require$$4$1 from 'assert'; import zlib from 'zlib'; import { EventEmitter } from 'events'; const Frameworks = [ { name: 'Next SSG', detectors: { some: [ { path: 'next.config.ts', matchContent: `(?:output|['"]output['"])\\s*:\\s*(?:['""]export['"])`, }, { path: 'next.config.js', matchContent: `(?:output|['"]output['"])\\s*:\\s*(?:['""]export['"])`, }, { path: 'next.config.mjs', matchContent: `(?:output|['"]output['"])\\s*:\\s*(?:['""]export['"])`, } ], }, info: { Framework: 'next ssg', OutputDir: 'out', IconPath: 'qcloud/ui/static/profession_static/6b7f3034-f645-4a42-b7b0-7f462c875e0c.svg', }, }, { name: "Next", detectors: { every: [{ matchPackage: "next" }], }, info: { Framework: "next", OutputDir: ".next", IconPath: "qcloud/ui/static/profession_static/6b7f3034-f645-4a42-b7b0-7f462c875e0c.svg", }, }, { name: "Gatsby", detectors: { every: [ { matchPackage: "gatsby", }, ], }, info: { Framework: "gatsby", OutputDir: "public", IconPath: "qcloud/ui/static/profession_static/8803d042-032e-428d-bdf1-877685f55f69.svg", }, }, { name: "Remix", detectors: { some: [ { matchPackage: "@remix-run/dev", }, { path: "remix.config.js", }, { path: "remix.config.mjs", }, ], }, info: { Framework: "remix", OutputDir: "build/client", IconPath: "qcloud/ui/static/profession_static/654f839d-6c7b-48c8-b508-052cc8c08036.svg", }, }, { name: "React Router", detectors: { some: [ { path: "vite.config.js", matchContent: "@react-router/dev/vite", }, { path: "vite.config.ts", matchContent: "@react-router/dev/vite", }, { path: "react-router.config.js", }, { path: "react-router.config.ts", }, ], }, info: { Framework: "react router", OutputDir: "build/client", IconPath: "qcloud/ui/static/profession_static/1b2d6ea2-9b43-409d-bc38-7d137fc06d7a.svg", }, }, { name: "Astro", detectors: { every: [ { matchPackage: "astro", }, ], }, info: { Framework: "astro", OutputDir: "dist", IconPath: "qcloud/ui/static/profession_static/ca12f111-0d36-4a39-afc5-f16849da7871.svg", }, }, { name: "Hexo", detectors: { every: [ { matchPackage: "hexo", }, ], }, info: { Framework: "hexo", OutputDir: "public", IconPath: "qcloud/ui/static/profession_static/b6751772-a56d-4165-ac68-4e2a9e534d97.svg", }, }, { name: "Eleventy", detectors: { every: [ { matchPackage: "@11ty/eleventy", }, ], }, info: { Framework: "eleventy", OutputDir: "_site", IconPath: "qcloud/ui/static/profession_static/447118a9-aa20-4879-b7a6-36612b961e8d.svg", }, }, { name: "Docusaurus", detectors: { some: [ { matchPackage: "docusaurus", }, { matchPackage: "@docusaurus/core", }, ], }, info: { Framework: "docusaurus", OutputDir: "build", IconPath: "qcloud/ui/static/profession_static/1d052730-bbd7-4dc3-ba4a-6107cfa1eab8.svg", }, }, { name: "Solid", detectors: { some: [ { matchPackage: "solid-js", }, ], }, info: { Framework: "solid", OutputDir: "dist", IconPath: "qcloud/ui/static/profession_static/ae844534-5591-4455-bf4b-ee8687367a8a.svg", }, }, { name: "Vue", detectors: { every: [ { matchPackage: "@vue/cli-service", }, ], }, info: { Framework: "vue", OutputDir: "dist", IconPath: "qcloud/ui/static/profession_static/8ba73416-3740-44b4-8bb5-212d09a2953e.svg", }, }, { name: "Angular", detectors: { every: [ { matchPackage: "@angular/cli", }, ], }, info: { Framework: "angular", OutputDir: "dist/angular/browser", IconPath: "qcloud/ui/static/profession_static/7b515046-378d-48b5-aca8-1277e7cb5255.svg", }, }, { name: "Svelte", detectors: { every: [ { matchPackage: "@sveltejs/kit", }, ], }, info: { Framework: "svelte", OutputDir: "build", IconPath: "qcloud/ui/static/profession_static/de27e697-b64d-46d5-918c-5c742f63731e.svg", }, }, { name: "React", detectors: { some: [ { matchPackage: "react-scripts", }, { matchPackage: "react-dev-utils", }, ], }, info: { Framework: "react", OutputDir: "build", IconPath: "qcloud/ui/static/profession_static/c5271b8c-2c52-4865-89e6-6c0bf59314ad.svg", }, }, { name: "Nuxt", detectors: { some: [ { matchPackage: "nuxt", }, { matchPackage: "nuxt3", }, { matchPackage: "nuxt-edge", }, ], }, info: { Framework: "nuxt", OutputDir: ".output", IconPath: "qcloud/ui/static/profession_static/f9c74e16-df30-47c3-87a7-01f4a04dbdbd.svg", }, }, { name: "Qwik", detectors: { every: [ { matchPackage: "@builder.io/qwik", }, ], }, info: { Framework: "qwik", OutputDir: "dist", IconPath: "qcloud/ui/static/profession_static/7cd2ac30-ccf4-4d91-a12c-58f9a591016e.svg", }, }, { name: "Hono", detectors: { every: [ { matchPackage: "hono", }, ], }, info: { Framework: "hono", OutputDir: "public", IconPath: "qcloud/ui/static/profession_static/6dc774fe-5521-4fa2-9f93-66d2dc735df7.svg", }, }, { name: "VitePress", detectors: { every: [ { matchPackage: "vitepress", }, ], }, info: { Framework: "vitepress", OutputDir: "dist", }, }, { name: "Vite", detectors: { every: [ { matchPackage: "vite", }, ], }, info: { Framework: "vite", OutputDir: "dist", IconPath: "qcloud/ui/static/profession_static/ff019b2f-655e-4ef2-8b33-23fe9bc1d761.svg", }, }, { name: "Other", detectors: {}, info: { Framework: "other", OutputDir: "", IconPath: "qcloud/ui/static/static_source_business/8264e769-f1d4-45aa-8cac-004ad351837c.svg", }, }, ]; function getOtherFramework() { const otherFramework = Frameworks.find((f) => f.name === "Other"); if (!otherFramework) { throw new Error("Other framework not found"); } return { ...otherFramework.info, BuildCmd: "", InstallCmd: "", }; } async function matchesLocal({ name, detectors, info, dirFiles, pkgStr, getFileContent, }) { if (!detectors) return undefined; const { every, some } = detectors; if (every !== undefined && !Array.isArray(every)) return undefined; if (some !== undefined && !Array.isArray(some)) return undefined; const result = []; if (every) { // 所有条件都得通过 const everyResult = await Promise.all(every.map((item) => check(item))); result.push(...everyResult); } if (some) { let someResult; // 至少一个条件通过 for (const item of some) { const itemResult = await check(item); if (itemResult) { someResult = itemResult; break; } } if (someResult) { result.push(someResult); } } if (!result.every((res) => !!res)) return undefined; return result[0]; async function check({ path, matchContent, matchPackage, }) { if (matchPackage && matchContent) { throw new Error(`Cannot specify "matchPackage" and "matchContent" in the same detector for "${name}"`); } if (matchPackage && path) { throw new Error(`Cannot specify "matchPackage" and "path" in the same detector for "${name}" because "path" is assumed to be "package.json".`); } if (!path && !matchPackage) { throw new Error(`Must specify either "path" or "matchPackage" in detector for "${name}".`); } if (matchPackage) { matchContent = `"(dev)?(d|D)ependencies":\\s*{[^}]*\"${matchPackage}\":\\s*\"(.+?)\"[^}]*}`; } // content 为带检测文件的内容,默认检测 package.json let content = pkgStr; if (path) { // 检查文件是否存在 if (!dirFiles.some((f) => f.name === path)) return undefined; // 读取文件内容 const fileContent = await getFileContent(path); if (fileContent === null) return undefined; content = fileContent; } if (matchContent) { const regex = new RegExp(matchContent, "m"); const match = content.match(regex); if (!match) { return undefined; } } return { ...info, }; } } // 新增:本地目录检测框架 /** * 本地检测项目框架 * @param projectRoot 本地项目根目录 * @returns 框架信息 */ async function describeFramework(projectRoot) { // 读取根目录文件列表 let dirFiles = []; try { dirFiles = fs$1.readdirSync(projectRoot).map((name) => ({ name })); } catch { return getOtherFramework(); } // 检查 package.json 是否存在 const hasPackageJson = dirFiles.some((f) => f.name === "package.json"); if (!hasPackageJson) { return getOtherFramework(); } // 读取 package.json 内容 let pkgStr = ""; try { const pkgPath = pathModule.join(projectRoot, "package.json"); pkgStr = fs$1.readFileSync(pkgPath, "utf-8"); } catch { pkgStr = JSON.stringify({ dependencies: {}, devDependencies: {} }); } // 本地读取文件内容的辅助函数 async function getFileContent(filePath) { try { return fs$1.readFileSync(pathModule.join(projectRoot, filePath), "utf-8"); } catch { return null; } } // 适配 matches 的参数 for (const framework of Frameworks) { const frameworkInfo = await matchesLocal({ ...framework, dirFiles, pkgStr, getFileContent, }); if (frameworkInfo !== undefined) { const result = { ...frameworkInfo, BuildCmd: "npm run build", InstallCmd: "npm install", }; if (fs$1.existsSync(pathModule.join(projectRoot, "yarn.lock"))) { result.BuildCmd = "yarn build"; result.InstallCmd = "yarn install"; } if (fs$1.existsSync(pathModule.join(projectRoot, "pnpm-lock.yaml"))) { result.BuildCmd = "pnpm run build"; result.InstallCmd = "pnpm install"; } if (fs$1.existsSync(pathModule.join(projectRoot, "bun.lockb"))) { result.BuildCmd = "bun run build"; result.InstallCmd = "bun install"; } return result; } } return getOtherFramework(); } /** * 匹配框架 * @param params 匹配参数 * @returns 如果匹配到的框架,则返回对应框架信息,否则返回 undefined */ async function matchesRemote(params) { const { name, detectors, info, body, pkgStr, rootDir, retDir, adapter } = params; if (!detectors) { return; } const { every, some } = detectors; if (every !== undefined && !Array.isArray(every)) return; if (some !== undefined && !Array.isArray(some)) return; const result = []; if (every) { // 所有条件都得通过 const everyResult = await Promise.all(every.map((item) => check(item))); result.push(...everyResult); } if (some) { let someResult; // 至少一个条件通过 for (const item of some) { const itemResult = await check(item); if (itemResult) { someResult = itemResult; break; } } result.push(someResult); } if (!result.every((res) => !!res)) return; return result[0]; /** * 检查单个检测器 */ async function check(detector) { const { path, matchPackage } = detector; let { matchContent } = detector; // 参数校验 validateDetector(detector, name); // 如果指定了 matchPackage,转换为 matchContent if (matchPackage) { matchContent = `"(dev)?(d|D)ependencies":\\s*{[^}]*"${matchPackage}":\\s*"(.+?)"[^}]*}`; } // 获取文件内容 const content = await getFileContent(path); if (content === null) return; // 匹配内容 if (matchContent) { const regex = new RegExp(matchContent, "m"); const match = content.match(regex); if (!match) { return; } } return { ...info }; } /** * 获取文件内容 */ async function getFileContent(path) { // 默认检测 package.json if (!path) { return pkgStr; } // 检查文件是否存在 if (!retDir.data.some((f) => f.name === path)) { return null; } // 通过适配器获取文件内容 const fileData = await adapter.getContents(body, rootDir, path); if (!fileData) { return null; } try { return Buffer.from(fileData.data.content, "base64").toString(); } catch { return null; } } } /** * 校验检测器参数 */ function validateDetector(detector, frameworkName) { const { path, matchContent, matchPackage } = detector; if (matchPackage && matchContent) { throw new Error(`Cannot specify "matchPackage" and "matchContent" in the same detector for "${frameworkName}"`); } if (matchPackage && path) { throw new Error(`Cannot specify "matchPackage" and "path" in the same detector for "${frameworkName}" because "path" is assumed to be "package.json".`); } if (!path && !matchPackage) { throw new Error(`Must specify either "path" or "matchPackage" in detector for "${frameworkName}".`); } } function bind$2(fn, thisArg) { return function wrap() { return fn.apply(thisArg, arguments); }; } // utils is a library of generic helper functions non-specific to axios const {toString} = Object.prototype; const {getPrototypeOf} = Object; const {iterator, toStringTag: toStringTag$1} = Symbol; const kindOf = (cache => thing => { const str = toString.call(thing); return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); })(Object.create(null)); const kindOfTest = (type) => { type = type.toLowerCase(); return (thing) => kindOf(thing) === type }; const typeOfTest = type => thing => typeof thing === type; /** * Determine if a value is an Array * * @param {Object} val The value to test * * @returns {boolean} True if value is an Array, otherwise false */ const {isArray} = Array; /** * Determine if a value is undefined * * @param {*} val The value to test * * @returns {boolean} True if the value is undefined, otherwise false */ const isUndefined = typeOfTest('undefined'); /** * Determine if a value is a Buffer * * @param {*} val The value to test * * @returns {boolean} True if value is a Buffer, otherwise false */ function isBuffer$1(val) { return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); } /** * Determine if a value is an ArrayBuffer * * @param {*} val The value to test * * @returns {boolean} True if value is an ArrayBuffer, otherwise false */ const isArrayBuffer = kindOfTest('ArrayBuffer'); /** * Determine if a value is a view on an ArrayBuffer * * @param {*} val The value to test * * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false */ function isArrayBufferView(val) { let result; if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { result = ArrayBuffer.isView(val); } else { result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); } return result; } /** * Determine if a value is a String * * @param {*} val The value to test * * @returns {boolean} True if value is a String, otherwise false */ const isString$1 = typeOfTest('string'); /** * Determine if a value is a Function * * @param {*} val The value to test * @returns {boolean} True if value is a Function, otherwise false */ const isFunction$1 = typeOfTest('function'); /** * Determine if a value is a Number * * @param {*} val The value to test * * @returns {boolean} True if value is a Number, otherwise false */ const isNumber = typeOfTest('number'); /** * Determine if a value is an Object * * @param {*} thing The value to test * * @returns {boolean} True if value is an Object, otherwise false */ const isObject = (thing) => thing !== null && typeof thing === 'object'; /** * Determine if a value is a Boolean * * @param {*} thing The value to test * @returns {boolean} True if value is a Boolean, otherwise false */ const isBoolean = thing => thing === true || thing === false; /** * Determine if a value is a plain Object * * @param {*} val The value to test * * @returns {boolean} True if value is a plain Object, otherwise false */ const isPlainObject = (val) => { if (kindOf(val) !== 'object') { return false; } const prototype = getPrototypeOf(val); return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag$1 in val) && !(iterator in val); }; /** * Determine if a value is an empty object (safely handles Buffers) * * @param {*} val The value to test * * @returns {boolean} True if value is an empty object, otherwise false */ const isEmptyObject = (val) => { // Early return for non-objects or Buffers to prevent RangeError if (!isObject(val) || isBuffer$1(val)) { return false; } try { return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; } catch (e) { // Fallback for any other objects that might cause RangeError with Object.keys() return false; } }; /** * Determine if a value is a Date * * @param {*} val The value to test * * @returns {boolean} True if value is a Date, otherwise false */ const isDate = kindOfTest('Date'); /** * Determine if a value is a File * * @param {*} val The value to test * * @returns {boolean} True if value is a File, otherwise false */ const isFile = kindOfTest('File'); /** * Determine if a value is a Blob * * @param {*} val The value to test * * @returns {boolean} True if value is a Blob, otherwise false */ const isBlob = kindOfTest('Blob'); /** * Determine if a value is a FileList * * @param {*} val The value to test * * @returns {boolean} True if value is a File, otherwise false */ const isFileList = kindOfTest('FileList'); /** * Determine if a value is a Stream * * @param {*} val The value to test * * @returns {boolean} True if value is a Stream, otherwise false */ const isStream = (val) => isObject(val) && isFunction$1(val.pipe); /** * Determine if a value is a FormData * * @param {*} thing The value to test * * @returns {boolean} True if value is an FormData, otherwise false */ const isFormData = (thing) => { let kind; return thing && ( (typeof FormData === 'function' && thing instanceof FormData) || ( isFunction$1(thing.append) && ( (kind = kindOf(thing)) === 'formdata' || // detect form-data instance (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]') ) ) ) }; /** * Determine if a value is a URLSearchParams object * * @param {*} val The value to test * * @returns {boolean} True if value is a URLSearchParams object, otherwise false */ const isURLSearchParams = kindOfTest('URLSearchParams'); const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); /** * Trim excess whitespace off the beginning and end of a string * * @param {String} str The String to trim * * @returns {String} The String freed of excess whitespace */ const trim = (str) => str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); /** * Iterate over an Array or an Object invoking a function for each item. * * If `obj` is an Array callback will be called passing * the value, index, and complete array for each item. * * If 'obj' is an Object callback will be called passing * the value, key, and complete object for each property. * * @param {Object|Array} obj The object to iterate * @param {Function} fn The callback to invoke for each item * * @param {Boolean} [allOwnKeys = false] * @returns {any} */ function forEach(obj, fn, {allOwnKeys = false} = {}) { // Don't bother if no value provided if (obj === null || typeof obj === 'undefined') { return; } let i; let l; // Force an array if not already something iterable if (typeof obj !== 'object') { /*eslint no-param-reassign:0*/ obj = [obj]; } if (isArray(obj)) { // Iterate over array values for (i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { // Buffer check if (isBuffer$1(obj)) { return; } // Iterate over object keys const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); const len = keys.length; let key; for (i = 0; i < len; i++) { key = keys[i]; fn.call(null, obj[key], key, obj); } } } function findKey(obj, key) { if (isBuffer$1(obj)){ return null; } key = key.toLowerCase(); const keys = Object.keys(obj); let i = keys.length; let _key; while (i-- > 0) { _key = keys[i]; if (key === _key.toLowerCase()) { return _key; } } return null; } const _global = (() => { /*eslint no-undef:0*/ if (typeof globalThis !== "undefined") return globalThis; return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global) })(); const isContextDefined = (context) => !isUndefined(context) && context !== _global; /** * Accepts varargs expecting each argument to be an object, then * immutably merges the properties of each object and returns result. * * When multiple objects contain the same key the later object in * the arguments list will take precedence. * * Example: * * ```js * var result = merge({foo: 123}, {foo: 456}); * console.log(result.foo); // outputs 456 * ``` * * @param {Object} obj1 Object to merge * * @returns {Object} Result of all merge properties */ function merge(/* obj1, obj2, obj3, ... */) { const {caseless} = isContextDefined(this) && this || {}; const result = {}; const assignValue = (val, key) => { const targetKey = caseless && findKey(result, key) || key; if (isPlainObject(result[targetKey]) && isPlainObject(val)) { result[targetKey] = merge(result[targetKey], val); } else if (isPlainObject(val)) { result[targetKey] = merge({}, val); } else if (isArray(val)) { result[targetKey] = val.slice(); } else { result[targetKey] = val; } }; for (let i = 0, l = arguments.length; i < l; i++) { arguments[i] && forEach(arguments[i], assignValue); } return result; } /** * Extends object a by mutably adding to it the properties of object b. * * @param {Object} a The object to be extended * @param {Object} b The object to copy properties from * @param {Object} thisArg The object to bind function to * * @param {Boolean} [allOwnKeys] * @returns {Object} The resulting value of object a */ const extend = (a, b, thisArg, {allOwnKeys}= {}) => { forEach(b, (val, key) => { if (thisArg && isFunction$1(val)) { a[key] = bind$2(val, thisArg); } else { a[key] = val; } }, {allOwnKeys}); return a; }; /** * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * * @param {string} content with BOM * * @returns {string} content value without BOM */ const stripBOM = (content) => { if (content.charCodeAt(0) === 0xFEFF) { content = content.slice(1); } return content; }; /** * Inherit the prototype methods from one constructor into another * @param {function} constructor * @param {function} superConstructor * @param {object} [props] * @param {object} [descriptors] * * @returns {void} */ const inherits = (constructor, superConstructor, props, descriptors) => { constructor.prototype = Object.create(superConstructor.prototype, descriptors); constructor.prototype.constructor = constructor; Object.defineProperty(constructor, 'super', { value: superConstructor.prototype }); props && Object.assign(constructor.prototype, props); }; /** * Resolve object with deep prototype chain to a flat object * @param {Object} sourceObj source object * @param {Object} [destObj] * @param {Function|Boolean} [filter] * @param {Function} [propFilter] * * @returns {Object} */ const toFlatObject = (sourceObj, destObj, filter, propFilter) => { let props; let i; let prop; const merged = {}; destObj = destObj || {}; // eslint-disable-next-line no-eq-null,eqeqeq if (sourceObj == null) return destObj; do { props = Object.getOwnPropertyNames(sourceObj); i = props.length; while (i-- > 0) { prop = props[i]; if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { destObj[prop] = sourceObj[prop]; merged[prop] = true; } } sourceObj = filter !== false && getPrototypeOf(sourceObj); } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); return destObj; }; /** * Determines whether a string ends with the characters of a specified string * * @param {String} str * @param {String} searchString * @param {Number} [position= 0] * * @returns {boolean} */ const endsWith = (str, searchString, position) => { str = String(str); if (position === undefined || position > str.length) { position = str.length; } position -= searchString.length; const lastIndex = str.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; }; /** * Returns new array from array like object or null if failed * * @param {*} [thing] * * @returns {?Array} */ const toArray = (thing) => { if (!thing) return null; if (isArray(thing)) return thing; let i = thing.length; if (!isNumber(i)) return null; const arr = new Array(i); while (i-- > 0) { arr[i] = thing[i]; } return arr; }; /** * Checking if the Uint8Array exists and if it does, it returns a function that checks if the * thing passed in is an instance of Uint8Array * * @param {TypedArray} * * @returns {Array} */ // eslint-disable-next-line func-names const isTypedArray = (TypedArray => { // eslint-disable-next-line func-names return thing => { return TypedArray && thing instanceof TypedArray; }; })(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); /** * For each entry in the object, call the function with the key and value. * * @param {Object<any, any>} obj - The object to iterate over. * @param {Function} fn - The function to call for each entry. * * @returns {void} */ const forEachEntry = (obj, fn) => { const generator = obj && obj[iterator]; const _iterator = generator.call(obj); let result; while ((result = _iterator.next()) && !result.done) { const pair = result.value; fn.call(obj, pair[0], pair[1]); } }; /** * It takes a regular expression and a string, and returns an array of all the matches * * @param {string} regExp - The regular expression to match against. * @param {string} str - The string to search. * * @returns {Array<boolean>} */ const matchAll = (regExp, str) => { let matches; const arr = []; while ((matches = regExp.exec(str)) !== null) { arr.push(matches); } return arr; }; /* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ const isHTMLForm = kindOfTest('HTMLFormElement'); const toCamelCase = str => { return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) { return p1.toUpperCase() + p2; } ); }; /* Creating a function that will check if an object has a property. */ const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); /** * Determine if a value is a RegExp object * * @param {*} val The value to test * * @returns {boolean} True if value is a RegExp object, otherwise false */ const isRegExp = kindOfTest('RegExp'); const reduceDescriptors = (obj, reducer) => { const descriptors = Object.getOwnPropertyDescriptors(obj); const reducedDescriptors = {}; forEach(descriptors, (descriptor, name) => { let ret; if ((ret = reducer(descriptor, name, obj)) !== false) { reducedDescriptors[name] = ret || descriptor; } }); Object.defineProperties(obj, reducedDescriptors); }; /** * Makes all methods read-only * @param {Object} obj */ const freezeMethods = (obj) => { reduceDescriptors(obj, (descriptor, name) => { // skip restricted props in strict mode if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { return false; } const value = obj[name]; if (!isFunction$1(value)) return; descriptor.enumerable = false; if ('writable' in descriptor) { descriptor.writable = false; return; } if (!descriptor.set) { descriptor.set = () => { throw Error('Can not rewrite read-only method \'' + name + '\''); }; } }); }; const toObjectSet = (arrayOrString, delimiter) => { const obj = {}; const define = (arr) => { arr.forEach(value => { obj[value] = true; }); }; isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); return obj; }; const noop$1 = () => {}; const toFiniteNumber = (value, defaultValue) => { return value != null && Number.isFinite(value = +value) ? value : defaultValue; }; /** * If the thing is a FormData object, return true, otherwise return false. * * @param {unknown} thing - The thing to check. * * @returns {boolean} */ function isSpecCompliantForm(thing) { return !!(thing && isFunction$1(thing.append) && thing[toStringTag$1] === 'FormData' && thing[iterator]); } const toJSONObject = (obj) => { const stack = new Array(10); const visit = (source, i) => { if (isObject(source)) { if (stack.indexOf(source) >= 0) { return; } //Buffer check if (isBuffer$1(source)) { return source; } if(!('toJSON' in source)) { stack[i] = source; const target = isArray(source) ? [] : {}; forEach(source, (value, key) => { const reducedValue = visit(value, i + 1); !isUndefined(reducedValue) && (target[key] = reducedValue); }); stack[i] = undefined; return target; } } return source; }; return visit(obj, 0); }; const isAsyncFn = kindOfTest('AsyncFunction'); const isThenable = (thing) => thing && (isObject(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); // original code // https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 const _setImmediate = ((setImmediateSupported, postMessageSupported) => { if (setImmediateSupported) { return setImmediate; } return postMessageSupported ? ((token, callbacks) => { _global.addEventListener("message", ({source, data}) => { if (source === _global && data === token) { callbacks.length && callbacks.shift()(); } }, false); return (cb) => { callbacks.push(cb); _global.postMessage(token, "*"); } })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); })( typeof setImmediate === 'function', isFunction$1(_global.postMessage) ); const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); // ********************* const isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); var utils$1 = { isArray, isArrayBuffer, isBuffer: isBuffer$1, isFormData, isArrayBufferView, isString: isString$1, isNumber, isBoolean, isObject, isPlainObject, isEmptyObject, isReadableStream, isRequest, isResponse, isHeaders, isUndefined, isDate, isFile, isBlob, isRegExp, isFunction: isFunction$1, isStream, isURLSearchParams, isTypedArray, isFileList, forEach, merge, extend, trim, stripBOM, inherits, toFlatObject, kindOf, kindOfTest, endsWith, toArray, forEachEntry, matchAll, isHTMLForm, hasOwnProperty, hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection reduceDescriptors, freezeMethods, toObjectSet, toCamelCase, noop: noop$1, toFiniteNumber, findKey, global: _global, isContextDefined, isSpecCompliantForm, toJSONObject, isAsyncFn, isThenable, setImmediate: _setImmediate, asap, isIterable }; /** * Create an Error with the specified message, config, error code, request and response. * * @param {string} message The error message. * @param {string} [code] The error code (for example, 'ECONNABORTED'). * @param {Object} [config] The config. * @param {Object} [request] The request. * @param {Object} [response] The response. * * @returns {Error} The created error. */ function AxiosError(message, code, config, request, response) { Error.call(this); if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } else { this.stack = (new Error()).stack; } this.message = message; this.name = 'AxiosError'; code && (this.code = code); config && (this.config = config); request && (this.request = request); if (response) { this.response = response; this.status = response.status ? response.status : null; } } utils$1.inherits(AxiosError, Error, { toJSON: function toJSON() { return { // Standard message: this.message, name: this.name, // Microsoft description: this.description, number: this.number, // Mozilla fileName: this.fileName, lineNumber: this.lineNumber, columnNumber: this.columnNumber, stack: this.stack, // Axios config: utils$1.toJSONObject(this.config), code: this.code, status: this.status }; } }); const prototype$1 = AxiosError.prototype; const descriptors = {}; [ 'ERR_BAD_OPTION_VALUE', 'ERR_BAD_OPTION', 'ECONNABORTED', 'ETIMEDOUT', 'ERR_NETWORK', 'ERR_FR_TOO_MANY_REDIRECTS', 'ERR_DEPRECATED', 'ERR_BAD_RESPONSE', 'ERR_BAD_REQUEST', 'ERR_CANCELED', 'ERR_NOT_SUPPORT', 'ERR_INVALID_URL' // eslint-disable-next-line func-names ].forEach(code => { descriptors[code] = {value: code}; }); Object.defineProperties(AxiosError, descriptors); Object.defineProperty(prototype$1, 'isAxiosError', {value: true}); // eslint-disable-next-line func-names AxiosError.from = (error, code, config, request, response, customProps) => { const axiosError = Object.create(prototype$1); utils$1.toFlatObject(error, axiosError, function filter(obj) { return obj !== Error.prototype; }, prop => { return prop !== 'isAxiosError'; }); AxiosError.call(axiosError, error.message, code, config, request, response); axiosError.cause = error; axiosError.name = error.name; customProps && Object.assign(axiosError, customProps); return axiosError; }; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var Stream$2 = stream.Stream; var util$2 = require$$1; var delayed_stream = DelayedStream$1; function DelayedStream$1() { this.source = null; this.dataSize = 0; this.maxDataSize = 1024 * 1024; this.pauseStream = true; this._maxDataSizeExceeded = false; this._released = false; this._bufferedEvents = []; } util$2.inherits(DelayedStream$1, Stream$2); DelayedStream$1.create = function(source, options) { var delayedStream = new this(); options = options || {}; for (var option in options) { delayedStream[option] = options[option]; } delayedStream.source = source; var realEmit = source.emit; source.emit = function() { delayedStream._handleEmit(arguments); return realEmit.apply(source, arguments); }; source.on('error', function() {}); if (delayedStream.pauseStream) { source.pause(); } return delayedStream; }; Object.defineProperty(DelayedStream$1.prototype, 'readable', { configurable: true, enumerable: true, get: function() { return this.source.readable; } }); DelayedStream$1.prototype.setEncoding = function() { return this.source.setEncoding.apply(this.source, arguments); }; DelayedStream$1.prototype.resume = function() { if (!this._released) { this.release(); } this.source.resume(); }; DelayedStream$1.prototype.pause = function() { this.source.pause(); }; DelayedStream$1.prototype.release = function() { this._released = true; this._bufferedEvents.forEach(function(args) { this.emit.apply(this, args); }.bind(this)); this._bufferedEvents = []; }; DelayedStream$1.prototype.pipe = function() { var r = Stream$2.prototype.pipe.apply(this, arguments); this.resume(); return r; }; DelayedStream$1.prototype._handleEmit = function(args) { if (this._released) { this.emit.apply(this, args); return; } if (args[0] === 'data') { this.dataSize += args[1].length; this._checkIfMaxDataSizeExceeded(); } this._bufferedEvents.push(args); }; DelayedStream$1.prototype._checkIfMaxDataSizeExceeded = function() { if (this._maxDataSizeExceeded) { return; } if (this.dataSize <= this.maxDataSize) { return; } this._maxDataSizeExceeded = true; var message = 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; this.emit('error', new Error(message)); }; var util$1 = require$$1; var Stream$1 = stream.Stream; var DelayedStream = delayed_stream; var combined_stream = CombinedStream$1; function CombinedStream$1() { this.writable = false; this.readable = true; this.dataSize = 0; this.maxDataSize = 2 * 1024 * 1024; this.pauseStreams = true; this._released = false; this._streams = []; this._currentStream = null; this._insideLoop = false; this._pendingNext = false; } util$1.inherits(CombinedStream$1, Stream$1); CombinedStream$1.create = function(options) { var combinedStream = new this(); options = options || {}; for (var option in options) { combinedStream[option] = options[option]; } return combinedStream; }; CombinedStream$1.isStreamLike = function(stream) { return (typeof stream !== 'function') && (typeof stream !== 'string') && (typeof stream !== 'boolean') && (typeof stream !== 'number') && (!Buffer.isBuffer(stream)); }; CombinedStream$1.prototype.append = function(stream) { var isStreamLike = CombinedStream$1.isStreamLike(stream); if (isStreamLike) { if (!(stream instanceof DelayedStream)) { var newStream = DelayedStream.create(stream, { maxDataSize: Infinity, pauseStream: this.pauseStreams, }); stream.on('data', this._checkDataSize.bind(this)); stream = newStream; } this._handleErrors(stream); if (this.pauseStreams) { stream.pause(); } } this._streams.push(stream); return this; }; CombinedStream$1.prototype.pipe = function(dest, options) { Stream$1.prototype.pipe.call(this, dest, options); this.resume(); return dest; }; CombinedStream$1.prototype._getNext = function() { this._currentStream = null; if (this._insideLoop) { this._pendingNext = true; return; // defer call } this._insideLoop = true; try { do { this._pendingNext = false; this._realGetNext(); } while (this._pendingNext); } finally { this._insideLoop = false; } }; CombinedStream$1.prototype._realGetNext = function() { var stream = this._streams.shift(); if (typeof stream == 'undefined') { this.end(); return; } if (typeof stream !== 'function') { this._pipeNext(stream); return; } var getStream = stream; getStream(function(stream) { var isStreamLike = CombinedStream$1.isStreamLike(stream); if (isStreamLike) { stream.on('data', this._checkDataSize.bind(this)); this._handleErrors(stream); } this._pipeNext(stream); }.bind(this)); }; CombinedStream$1.prototype._pipeNext = function(stream) { this._currentStream = stream; var isStreamLike = CombinedStream$1.isStreamLike(stream); if (isStreamLike) { stream.on('end', this._getNext.bind(this)); stream.pipe(this, {end: false}); return; } var value = stream; this.write(value); this._getNext(); }; CombinedStream$1.prototype._handleErrors = function(stream) { var self = this; stream.on('error', function(err) { self._emitError(err); }); }; CombinedStream$1.prototype.write = function(data) { this.emit('data', data); }; CombinedStream$1.prototype.pause = function() { if (!this.pauseStreams) { return; } if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); this.emit('pause'); }; CombinedStream$1.prototype.resume = function() { if (!this._released) { this._released = true; this.writable = true; this._getNext(); } if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); this.emit('resume'); }; CombinedStream$1.prototype.end = function() { this._reset(); this.emit('end'); }; CombinedStream$1.prototype.destroy = function() { this._reset(); this.emit('close'); }; CombinedStream$1.prototype._reset = function() { this.writable = false; this._streams = []; this._currentStream = null; }; CombinedStream$1.prototype._checkDataSize = function() { this._updateDataSize(); if (this.dataSize <= this.maxDataSize) { return; } var message = 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; this._emitError(new Error(message)); }; CombinedStream$1.prototype._updateDataSize = function() { this.dataSize = 0; var self = this; this._streams.forEach(function(stream) { if (!stream.dataSize) { return; } self.dataSize += stream.dataSize; }); if (this._currentStream && this._currentStream.dataSize) { this.dataSize += this._currentStream.dataSize; } }; CombinedStream$1.prototype._emitError = function(err) { this._reset(); this.emit('error', err); }; var mimeTypes = {}; var require$$0 = { "application/1d-interleaved-parityfec": { source: "iana" }, "application/3gpdash-qoe-report+xml": { source: "iana", charset: "UTF-8", compressible: true }, "application/3gpp-ims+xml": { source: "iana", compressible: true }, "application/3gpphal+json": { source: "iana", compressible: true }, "application/3gpphalforms+json": { source: "iana", compressible: true }, "application/a2l": { source: "iana" }, "application/ace+cbor": { source: "iana" }, "application/activemessage": { source: "iana" }, "application/activity+json": { source: "iana", compressible: true }, "application/alto-costmap+json": { source: "iana", compressible: true }, "application/alto-costmapfilter+json": { source: "iana", compressible: true }, "application/alto-directory+json": { source: "iana", compressible: true }, "application/alto-endpointcost+json": { source: "iana", compressible: true }, "application/alto-endpointcostparams+json": { source: "iana", compressible: true }, "application/alto-endpointprop+json": { source: "iana", compressible: true }, "application/alto-endpointpropparams+json": { source: "iana", compressible: true }, "application/alto-error+json": { source: "iana", compressible: true }, "application/alto-networkmap+json": { source: "iana", compressible: true }, "application/alto-networkmapfilter+json": { source: "iana", compressible: true }, "application/alto-updatestreamcontrol+json": { source: "iana", compressible: true }, "application/alto-updatestreamparams+json": { source: "iana", compressible: true }, "application/aml": { source: "iana" }, "application/andrew-inset": { source: "iana", extensions: [ "ez" ] }, "application/applefile": { source: "iana" }, "application/applixware": { source: "apache", extensions: [ "aw" ] }, "application/at+jwt": { source: "iana" }, "application/atf": { source: "iana" }, "application/atfx": { source: "iana" }, "application/atom+xml": { source: "iana", compressible: true, extensions: [ "atom" ] }, "application/atomcat+xml": { source: "iana", compressible: true, extensions: [ "atomcat" ] }, "application/atomdeleted+xml": { source: "iana", compressible: true, extensions: [ "atomdeleted" ] }, "application/atomicmail": { source: "iana" }, "application/atomsvc+xml": { source: "iana", compressible: true, extensions: [ "atomsvc" ] }, "application/atsc-dwd+xml": { source: "iana", compressible: true, extensions: [ "dwd" ] }, "application/atsc-dynamic-event-message": { source: "iana" }, "application/atsc-held+xml": { source: "iana", compressible: true, extensions: [ "held" ] }, "application/atsc-rdt+json": { source: "iana", compressible: true }, "application/atsc-rsat+xml": { source: "iana", compressible: true, extensions: [ "rsat" ] }, "application/atxml": { source: "iana" }, "application/auth-policy+xml": { source: "iana", compressible: true }, "application/bacnet-xdd+zip": { source: "iana", compressible: false }, "application/batch-smtp": { source: "iana" }, "application/bdoc": { compressible: false, extensions: [ "bdoc" ] }, "application/beep+xml": { source: "iana", charset: "UTF-8", compressible: true }, "application/calendar+json": { source: "iana", compressible: true }, "application/calendar+xml": { source: "iana", compressible: true, extensions: [ "xcs" ] }, "application/call-completion": { source: "iana" }, "application/cals-1840": { source: "iana" }, "application/captive+json": { source: "iana", compressible: true }, "application/cbor": { source: "iana" }, "application/cbor-seq": { source: "iana" }, "application/cccex": { source: "iana" }, "application/ccmp+xml": { source: "iana", compressible: true }, "application/ccxml+xml": { source: "iana", compressible: true, extensions: [ "ccxml" ] }, "application/cdfx+xml": { source: "iana", compressible: true, extensions: [ "cdfx" ] }, "application/cdmi-capability": { source: "iana", extensions: [