@edgeone/framework-detect
Version:
A framework detection library for web projects
2,046 lines (1,857 loc) • 407 kB
JavaScript
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: [