From 7a2740b233a6a4acf653d7b961f84d68ff23233f Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 16:51:10 +0800 Subject: [PATCH 01/31] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflows/release-package-to-github.yml | 40 - ...package-to-npm.yml => release-package.yml} | 25 +- biome.json | 123 ++- getStorage.mjs | 98 --- index.js | 11 - lib/app.mjs | 26 - lib/done.mjs | 67 -- lib/index.js | 5 - lib/notification.mjs | 151 ---- lib/runScript.mjs | 27 - lib/wait.mjs | 10 - package-lock.json | 714 +++++++++++++++++- package.json | 99 ++- polyfill/Console.mjs | 175 ----- polyfill/Lodash.mjs | 72 -- polyfill/Storage.mjs | 257 ------- polyfill/fetch.mjs | 202 ----- polyfill/index.js | 5 - rslib.config.ts | 19 + src/env.d.ts | 11 + src/getStorage.ts | 109 +++ src/index.ts | 11 + src/lib/app.ts | 28 + src/lib/done.ts | 115 +++ lib/environment.mjs => src/lib/environment.ts | 23 +- src/lib/index.ts | 5 + src/lib/notification.ts | 152 ++++ src/lib/runScript.ts | 49 ++ lib/time.mjs => src/lib/time.ts | 7 +- src/lib/wait.ts | 6 + src/polyfill/Console.ts | 186 +++++ src/polyfill/Lodash.ts | 22 + .../polyfill/StatusTexts.ts | 0 src/polyfill/Storage.ts | 174 +++++ src/polyfill/fetch.ts | 218 ++++++ src/polyfill/index.ts | 5 + tsconfig.json | 34 +- 37 files changed, 1978 insertions(+), 1303 deletions(-) delete mode 100644 .github/workflows/release-package-to-github.yml rename .github/workflows/{release-package-to-npm.yml => release-package.yml} (66%) delete mode 100644 getStorage.mjs delete mode 100644 index.js delete mode 100644 lib/app.mjs delete mode 100644 lib/done.mjs delete mode 100644 lib/index.js delete mode 100644 lib/notification.mjs delete mode 100644 lib/runScript.mjs delete mode 100644 lib/wait.mjs delete mode 100644 polyfill/Console.mjs delete mode 100644 polyfill/Lodash.mjs delete mode 100644 polyfill/Storage.mjs delete mode 100644 polyfill/fetch.mjs delete mode 100644 polyfill/index.js create mode 100644 rslib.config.ts create mode 100644 src/env.d.ts create mode 100644 src/getStorage.ts create mode 100644 src/index.ts create mode 100644 src/lib/app.ts create mode 100644 src/lib/done.ts rename lib/environment.mjs => src/lib/environment.ts (57%) create mode 100644 src/lib/index.ts create mode 100644 src/lib/notification.ts create mode 100644 src/lib/runScript.ts rename lib/time.mjs => src/lib/time.ts (88%) create mode 100644 src/lib/wait.ts create mode 100644 src/polyfill/Console.ts create mode 100644 src/polyfill/Lodash.ts rename polyfill/StatusTexts.mjs => src/polyfill/StatusTexts.ts (100%) create mode 100644 src/polyfill/Storage.ts create mode 100644 src/polyfill/fetch.ts create mode 100644 src/polyfill/index.ts diff --git a/.github/workflows/release-package-to-github.yml b/.github/workflows/release-package-to-github.yml deleted file mode 100644 index 1774884..0000000 --- a/.github/workflows/release-package-to-github.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Release Node.js Package to GitHub Package Registry - -on: - push: - # Sequence of patterns matched against refs/tags - tags: - - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 16 - - run: npm ci - - run: npm test - - publish-gpr: - needs: build - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - uses: actions/checkout@v4 - - name: Update local package.json version from release tag - uses: BellCubeDev/update-package-version-by-release-tag@v2 - with: - version: ${{ github.ref_name }} - keep-v: "false" # If set to "true", will not remove any 'v' prefix from the version number. - ignore-semver-check: "false" # If set to "true", will not check if the version number is a valid semver version. - - uses: actions/setup-node@v4 - with: - registry-url: 'https://npm.pkg.github.com' - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-package-to-npm.yml b/.github/workflows/release-package.yml similarity index 66% rename from .github/workflows/release-package-to-npm.yml rename to .github/workflows/release-package.yml index fdb3557..ed1a7be 100644 --- a/.github/workflows/release-package-to-npm.yml +++ b/.github/workflows/release-package.yml @@ -1,4 +1,4 @@ -name: Release Node.js Package to NPM Registry +name: Release on: push: @@ -7,22 +7,14 @@ on: - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 16 - - run: npm ci - - run: npm test - - publish-gpr: - needs: build + publish: runs-on: ubuntu-latest permissions: packages: write contents: read + strategy: + matrix: + registry: ["https://registry.npmjs.org", "https://npm.pkg.github.com"] steps: - uses: actions/checkout@v4 - name: Update local package.json version from release tag @@ -33,9 +25,10 @@ jobs: ignore-semver-check: "false" # If set to "true", will not check if the version number is a valid semver version. - uses: actions/setup-node@v4 with: - node-version: 16 - registry-url: 'https://registry.npmjs.org' + node-version: 20 + registry-url: ${{ matrix.registry }} - run: npm ci + - run: npm run build - run: npm publish --access public env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ matrix.registry == 'https://registry.npmjs.org' && secrets.NPM_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/biome.json b/biome.json index 37d3d39..2d4a3af 100644 --- a/biome.json +++ b/biome.json @@ -1,78 +1,53 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "files": { - "ignore": [ - "**/*.bundle.js" - ], - "ignoreUnknown": false - }, + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "organizeImports": { + "enabled": true + }, + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "formatter": { + "enabled": true, + "useEditorconfig": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 120, + "attributePosition": "auto", + "bracketSpacing": true + }, + "javascript": { "formatter": { - "enabled": true, - "indentStyle": "tab", - "indentWidth": 2, - "lineEnding": "lf", - "lineWidth": 320 - }, - "javascript": { - "formatter": { - "arrowParentheses": "asNeeded", - "bracketSameLine": true, - "quoteStyle": "double" - } - }, - "json": { - "parser": { - "allowComments": true, - "allowTrailingCommas": true - } - }, - "linter": { - "enabled": true, - "rules": { - "complexity": { - "noForEach": "off", - "noStaticOnlyClass": "off", - "noUselessSwitchCase": "off", - "useArrowFunction": "info", - "useFlatMap": "off", - "useLiteralKeys": "info" - }, - "correctness": { - "noInnerDeclarations": "info", - "noSelfAssign": "off", - "noSwitchDeclarations": "info", - "noUnsafeOptionalChaining": "info" - }, - "performance": { - "noDelete": "info" - }, - "recommended": true, - "style": { - "noNegationElse": "off", - "noParameterAssign": "off", - "noUselessElse": "off", - "noVar": "info", - "useDefaultParameterLast": "info", - "useForOf": "error", - "useNodejsImportProtocol": "error", - "useNumberNamespace": "error", - "useSingleVarDeclarator": "off" - }, - "suspicious": { - "noAssignInExpressions": "info", - "noDoubleEquals": "info", - "noFallthroughSwitchClause": "info", - "noGlobalIsNan": "off", - "useDefaultSwitchClauseLast": "off" - } - } - }, - "organizeImports": { - "enabled": true - }, - "vcs": { - "clientKind": "git", - "enabled": true, - "useIgnoreFile": true + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true } + }, + "css": { + "parser": { + "cssModules": true + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "noUselessSwitchCase": "off", + "noForEach": "off" + }, + "suspicious": { + "noExplicitAny": "warn" + } + } + } } diff --git a/getStorage.mjs b/getStorage.mjs deleted file mode 100644 index f2f1528..0000000 --- a/getStorage.mjs +++ /dev/null @@ -1,98 +0,0 @@ -import { Console } from "./polyfill/Console.mjs"; -import { Lodash as _ } from "./polyfill/Lodash.mjs"; -import { Storage } from "./polyfill/Storage.mjs"; - -/** - * Get Storage Variables - * @link https://github.com/NanoCat-Me/utils/blob/main/getStorage.mjs - * @author VirgilClyne - * @param {string} key - Persistent Store Key - * @param {array | string} names - Platform Names - * @param {object} database - Default Database - * @return {object} { Settings, Caches, Configs } - */ -export function getStorage(key, names, database) { - names = [names].flat(Number.POSITIVE_INFINITY); - //Console.log("☑️ getStorage"); - /***************** Default *****************/ - const Store = { Settings: database?.Default?.Settings || {}, Configs: database?.Default?.Configs || {}, Caches: {} }; - //Console.debug("Default", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`); - /***************** Database *****************/ - names.forEach(name => { - Store.Settings = { ...Store.Settings, ...database?.[name]?.Settings }; - Store.Configs = { ...Store.Configs, ...database?.[name]?.Configs }; - }); - //Console.debug("Database", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`); - /***************** Argument *****************/ - switch (typeof $argument) { - // biome-ignore lint/suspicious/noFallthroughSwitchClause: - case "string": - $argument = Object.fromEntries($argument.split("&").map(item => item.split("=", 2).map(i => i.replace(/\"/g, "")))); - case "object": { - const argument = {}; - Object.keys($argument).forEach(key => _.set(argument, key, $argument[key])); - //Console.debug(`✅ $argument`, `argument: ${JSON.stringify(argument)}`); - Store.Settings = { ...Store.Settings, ...argument }; - break; - } - case "undefined": - break; - } - //Console.debug("$argument", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`); - /***************** BoxJs *****************/ - // 包装为局部变量,用完释放内存 - // BoxJs的清空操作返回假值空字符串, 逻辑或操作符会在左侧操作数为假值时返回右侧操作数。 - const BoxJs = Storage.getItem(key); - if (BoxJs) { - //Console.debug("BoxJs", `BoxJs类型: ${typeof BoxJs}`, `BoxJs内容: ${JSON.stringify(BoxJs || {})}`); - names.forEach(name => { - switch (typeof BoxJs?.[name]?.Settings) { - // biome-ignore lint/suspicious/noFallthroughSwitchClause: - case "string": - BoxJs[name].Settings = JSON.parse(BoxJs[name].Settings || "{}"); - case "object": - Store.Settings = { ...Store.Settings, ...BoxJs[name].Settings }; - break; - case "undefined": - break; - } - switch (typeof BoxJs?.[name]?.Caches) { - // biome-ignore lint/suspicious/noFallthroughSwitchClause: - case "string": - BoxJs[name].Caches = JSON.parse(BoxJs[name].Caches || "{}"); - case "object": - Store.Caches = { ...Store.Caches, ...BoxJs[name].Caches }; - break; - case "undefined": - break; - } - }); - //Console.debug("BoxJs", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`); - } - /***************** traverseObject *****************/ - traverseObject(Store.Settings, (key, value) => { - //Console.debug("☑️ traverseObject", `${key}: ${typeof value}`, `${key}: ${JSON.stringify(value)}`); - if (value === "true" || value === "false") - value = JSON.parse(value); // 字符串转Boolean - else if (typeof value === "string") { - if (value.includes(",")) - value = value.split(",").map(item => string2number(item)); // 字符串转数组转数字 - else value = string2number(value); // 字符串转数字 - } - return value; - }); - //Console.debug("✅ traverseObject", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`); - return Store; -} - -function traverseObject(o, c) { - for (const t in o) { - const n = o[t]; - o[t] = "object" === typeof n && null !== n ? traverseObject(n, c) : c(t, n); - } - return o; -} -function string2number(string) { - if (/^\d+$/.test(string)) string = Number.parseInt(string, 10); - return string; -} diff --git a/index.js b/index.js deleted file mode 100644 index 84c68c3..0000000 --- a/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export * from "./lib/app.mjs"; -export * from "./lib/done.mjs"; -export * from "./lib/notification.mjs"; -export * from "./lib/time.mjs"; -export * from "./lib/wait.mjs"; -export * from "./polyfill/Console.mjs"; -export * from "./polyfill/fetch.mjs"; -export * from "./polyfill/Lodash.mjs"; -export * from "./polyfill/StatusTexts.mjs"; -export * from "./polyfill/Storage.mjs"; -export * from "./getStorage.mjs"; diff --git a/lib/app.mjs b/lib/app.mjs deleted file mode 100644 index d74211d..0000000 --- a/lib/app.mjs +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Current app name - * - * @type {("Quantumult X" | "Loon" | "Shadowrocket" | "Node.js" | "Egern" | "Surge" | "Stash")} - */ -export const $app = (() => { - const keys = Object.keys(globalThis); - switch (true) { - case keys.includes("$task"): - return "Quantumult X"; - case keys.includes("$loon"): - return "Loon"; - case keys.includes("$rocket"): - return "Shadowrocket"; - case typeof module !== "undefined": - return "Node.js"; - case keys.includes("Egern"): - return "Egern"; - case keys.includes("$environment"): - if ($environment["surge-version"]) return "Surge"; - if ($environment["stash-version"]) return "Stash"; - return undefined; - default: - return undefined; - } -})(); diff --git a/lib/done.mjs b/lib/done.mjs deleted file mode 100644 index 1bb5098..0000000 --- a/lib/done.mjs +++ /dev/null @@ -1,67 +0,0 @@ -import { $app } from "./app.mjs"; -import { Console } from "../polyfill/Console.mjs"; -import { Lodash as _ } from "../polyfill/Lodash.mjs"; -import { StatusTexts } from "../polyfill/StatusTexts.mjs"; - -/** - * Complete the script execution - * - * @export - * @param {object} object - * @returns {void} - */ -export function done(object = {}) { - switch ($app) { - case "Surge": - if (object.policy) _.set(object, "headers.X-Surge-Policy", object.policy); - Console.log("🚩 执行结束!", `🕛 ${new Date().getTime() / 1000 - $script.startTime} 秒`); - $done(object); - break; - case "Loon": - if (object.policy) object.node = object.policy; - Console.log("🚩 执行结束!", `🕛 ${(new Date() - $script.startTime) / 1000} 秒`); - $done(object); - break; - case "Stash": - if (object.policy) _.set(object, "headers.X-Stash-Selected-Proxy", encodeURI(object.policy)); - Console.log("🚩 执行结束!", `🕛 ${(new Date() - $script.startTime) / 1000} 秒`); - $done(object); - break; - case "Egern": - Console.log("🚩 执行结束!"); - $done(object); - break; - case "Shadowrocket": - Console.log("🚩 执行结束!"); - $done(object); - break; - case "Quantumult X": - if (object.policy) _.set(object, "opts.policy", object.policy); - object = _.pick(object, ["status", "url", "headers", "body", "bodyBytes"]); - switch (typeof object.status) { - case "number": - object.status = `HTTP/1.1 ${object.status} ${StatusTexts[object.status]}`; - break; - case "string": - case "undefined": - break; - default: - throw new TypeError(`${Function.name}: 参数类型错误, status 必须为数字或字符串`); - } - if (object.body instanceof ArrayBuffer) { - object.bodyBytes = object.body; - object.body = undefined; - } else if (ArrayBuffer.isView(object.body)) { - object.bodyBytes = object.body.buffer.slice(object.body.byteOffset, object.body.byteLength + object.body.byteOffset); - object.body = undefined; - } else if (object.body) object.bodyBytes = undefined; - Console.log("🚩 执行结束!"); - $done(object); - break; - case "Node.js": - default: - Console.log("🚩 执行结束!"); - process.exit(1); - break; - } -} diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index c73a06f..0000000 --- a/lib/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./app.mjs"; -export * from "./done.mjs"; -export * from "./notification.mjs"; -export * from "./time.mjs"; -export * from "./wait.mjs"; diff --git a/lib/notification.mjs b/lib/notification.mjs deleted file mode 100644 index 940caad..0000000 --- a/lib/notification.mjs +++ /dev/null @@ -1,151 +0,0 @@ -import { $app } from "./app.mjs"; -import { Console } from "../polyfill/Console.mjs"; - -/** - * 系统通知 - * - * > 通知参数: 同时支持 QuanX 和 Loon 两种格式, EnvJs根据运行环境自动转换, Surge 环境不支持多媒体通知 - * - * 示例: - * $.msg(title, subtitle, body, "twitter://") - * $.msg(title, subtitle, body, { "open-url": "twitter://", "media-url": "https://github.githubassets.com/images/modules/open_graph/github-mark.png" }) - * $.msg(title, subtitle, body, { "open-url": "https://bing.com", "media-url": "https://github.githubassets.com/images/modules/open_graph/github-mark.png" }) - * - * @param {string} title 标题 - * @param {string} subtitle 副标题 - * @param {string} body 内容 - * @param {*} mutableContent 通知扩展字段 - * - */ -export function notification(title = `ℹ️ ${$app} 通知`, subtitle = "", body = "", content = {}) { - const mutableContent = MutableContent(content); - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - default: - $notification.post(title, subtitle, body, mutableContent); - break; - case "Quantumult X": - $notify(title, subtitle, body, mutableContent); - break; - case "Node.js": - break; - } - Console.group("📣 系统通知"); - Console.log(title, subtitle, body, JSON.stringify(mutableContent, null, 2)); - Console.groupEnd(); -} - -const MutableContent = content => { - const mutableContent = {}; - switch (typeof content) { - case undefined: - break; - case "string": - case "number": - case "boolean": - switch ($app) { - case "Surge": - case "Stash": - case "Egern": - default: - mutableContent.url = content; - break; - case "Loon": - case "Shadowrocket": - mutableContent.openUrl = content; - break; - case "Quantumult X": - mutableContent["open-url"] = content; - break; - case "Node.js": - break; - } - break; - case "object": { - const openUrl = content.open || content["open-url"] || content.url || content.openUrl; - const copyUrl = content.copy || content["update-pasteboard"] || content.updatePasteboard; - const mediaUrl = content.media || content["media-url"] || content.mediaUrl; - switch ($app) { - case "Surge": - case "Stash": - case "Egern": - case "Shadowrocket": - default: { - if (openUrl) { - mutableContent.action = "open-url"; - mutableContent.url = openUrl; - } - if (copyUrl) { - mutableContent.action = "clipboard"; - mutableContent.text = copyUrl; - } - if (mediaUrl) { - switch (true) { - case mediaUrl.startsWith("http"): // http 开头的网络地址 - mutableContent["media-url"] = mediaUrl; - break; - case mediaUrl.startsWith("data:"): { - // data 开头的 Base64 编码 - // data:image/png;base64,iVBORw0KGgo... - const base64RegExp = /^data:(?\w+\/\w+);base64,(?.+)/; - const { MIME, Base64 } = mediaUrl.match(base64RegExp).groups; - mutableContent["media-base64"] = Base64; - mutableContent["media-base64-mime"] = content.mime || MIME; - break; - } - default: { - mutableContent["media-base64"] = mediaUrl; - // https://stackoverflow.com/questions/57976898/how-to-get-mime-type-from-base-64-string - switch (true) { - case mediaUrl.startsWith("CiVQREYt"): - case mediaUrl.startsWith("JVBERi0"): - mutableContent["media-base64-mime"] = "application/pdf"; - break; - case mediaUrl.startsWith("R0lGODdh"): - case mediaUrl.startsWith("R0lGODlh"): - mutableContent["media-base64-mime"] = "image/gif"; - break; - case mediaUrl.startsWith("iVBORw0KGgo"): - mutableContent["media-base64-mime"] = "image/png"; - break; - case mediaUrl.startsWith("/9j/"): - mutableContent["media-base64-mime"] = "image/jpg"; - break; - case mediaUrl.startsWith("Qk02U"): - mutableContent["media-base64-mime"] = "image/bmp"; - break; - } - break; - } - } - } - if (content["auto-dismiss"]) mutableContent["auto-dismiss"] = content["auto-dismiss"]; - if (content.sound) mutableContent.sound = content.sound; - break; - } - case "Loon": { - if (openUrl) mutableContent.openUrl = openUrl; - if (mediaUrl?.startsWith("http")) mutableContent.mediaUrl = mediaUrl; - break; - } - case "Quantumult X": { - if (openUrl) mutableContent["open-url"] = openUrl; - if (mediaUrl?.startsWith("http")) mutableContent["media-url"] = mediaUrl; - if (copyUrl) mutableContent["update-pasteboard"] = copyUrl; - break; - } - case "Node.js": - break; - } - break; - } - default: - Console.error(`不支持的通知参数类型: ${typeof content}`, ""); - break; - } - return mutableContent; -}; diff --git a/lib/runScript.mjs b/lib/runScript.mjs deleted file mode 100644 index ec7aeeb..0000000 --- a/lib/runScript.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import { Console } from "../polyfill/Console.mjs"; -import { fetch } from "../polyfill/fetch.mjs"; -import { Lodash as _ } from "../polyfill/Lodash.mjs"; -import { Storage } from "../polyfill/Storage.mjs"; - -export async function runScript(script, runOpts) { - let httpapi = Storage.getItem("@chavy_boxjs_userCfgs.httpapi"); - httpapi = httpapi?.replace?.(/\n/g, "")?.trim(); - let httpapi_timeout = Storage.getItem("@chavy_boxjs_userCfgs.httpapi_timeout"); - httpapi_timeout = httpapi_timeout * 1 ?? 20; - httpapi_timeout = runOpts?.timeout ?? httpapi_timeout; - const [password, address] = httpapi.split("@"); - const request = { - url: `http://${address}/v1/scripting/evaluate`, - body: { - script_text: script, - mock_type: "cron", - timeout: httpapi_timeout, - }, - headers: { "X-Key": password, Accept: "*/*" }, - timeout: httpapi_timeout, - }; - await fetch(request).then( - response => response.body, - error => Console.error(error), - ); -} diff --git a/lib/wait.mjs b/lib/wait.mjs deleted file mode 100644 index 260e674..0000000 --- a/lib/wait.mjs +++ /dev/null @@ -1,10 +0,0 @@ -/** - * wait - * - * @export - * @param {number} [delay=1000] - * @returns {Promise} - */ -export function wait(delay = 1000) { - return new Promise(resolve => setTimeout(resolve, delay)); -} diff --git a/package-lock.json b/package-lock.json index c7860e7..23ac9be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,17 +7,704 @@ "name": "@nsnanocat/util", "license": "Apache-2.0", "dependencies": { - "pako": "^2.1.0" + "lodash": "^4.17.21" }, "devDependencies": { + "@biomejs/biome": "^1.9.2", + "@rslib/core": "^0.2.2", + "@types/lodash": "^4.17.13", + "@types/node": "^22.10.2", + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2", "typescript": "^5.6.3" + }, + "optionalDependencies": { + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/biome/-/biome-1.9.2.tgz", + "integrity": "sha512-4j2Gfwft8Jqp1X0qLYvK4TEy4xhTo4o6rlvJPsjPeEame8gsmbGQfOPBkw7ur+7/Z/f0HZmCZKqbMvR7vTXQYQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.2", + "@biomejs/cli-darwin-x64": "1.9.2", + "@biomejs/cli-linux-arm64": "1.9.2", + "@biomejs/cli-linux-arm64-musl": "1.9.2", + "@biomejs/cli-linux-x64": "1.9.2", + "@biomejs/cli-linux-x64-musl": "1.9.2", + "@biomejs/cli-win32-arm64": "1.9.2", + "@biomejs/cli-win32-x64": "1.9.2" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.2.tgz", + "integrity": "sha512-rbs9uJHFmhqB3Td0Ro+1wmeZOHhAPTL3WHr8NtaVczUmDhXkRDWScaxicG9+vhSLj1iLrW47itiK6xiIJy6vaA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.2.tgz", + "integrity": "sha512-BlfULKijNaMigQ9GH9fqJVt+3JTDOSiZeWOQtG/1S1sa8Lp046JHG3wRJVOvekTPL9q/CNFW1NVG8J0JN+L1OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.2.tgz", + "integrity": "sha512-T8TJuSxuBDeQCQzxZu2o3OU4eyLumTofhCxxFd3+aH2AEWVMnH7Z/c3QP1lHI5RRMBP9xIJeMORqDQ5j+gVZzw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.2.tgz", + "integrity": "sha512-ZATvbUWhNxegSALUnCKWqetTZqrK72r2RsFD19OK5jXDj/7o1hzI1KzDNG78LloZxftrwr3uI9SqCLh06shSZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.2.tgz", + "integrity": "sha512-T0cPk3C3Jr2pVlsuQVTBqk2qPjTm8cYcTD9p/wmR9MeVqui1C/xTVfOIwd3miRODFMrJaVQ8MYSXnVIhV9jTjg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.2.tgz", + "integrity": "sha512-CjPM6jT1miV5pry9C7qv8YJk0FIZvZd86QRD3atvDgfgeh9WQU0k2Aoo0xUcPdTnoz0WNwRtDicHxwik63MmSg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.2.tgz", + "integrity": "sha512-2x7gSty75bNIeD23ZRPXyox6Z/V0M71ObeJtvQBhi1fgrvPdtkEuw7/0wEHg6buNCubzOFuN9WYJm6FKoUHfhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.2", + "resolved": "https://bnpm.byted.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.2.tgz", + "integrity": "sha512-JC3XvdYcjmu1FmAehVwVV0SebLpeNTnO2ZaMdGCSOdS7f8O9Fq14T2P1gTG1Q29Q8Dt1S03hh0IdVpIZykOL8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://bnpm.byted.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://bnpm.byted.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://bnpm.byted.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" } }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", - "license": "(MIT AND Zlib)" + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://bnpm.byted.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://bnpm.byted.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@rsbuild/core": { + "version": "1.1.13", + "resolved": "https://bnpm.byted.org/@rsbuild/core/-/core-1.1.13.tgz", + "integrity": "sha512-XBL2hrin8731W6iTGGL+x3cv07n4vm2D7u6XHRwtQkRfySzAqGx7ThlQLdNX/dJwfsoQrYQuWl/qzaljjXtGtg==", + "dev": true, + "dependencies": { + "@rspack/core": "1.1.8", + "@rspack/lite-tapable": "~1.0.1", + "@swc/helpers": "^0.5.15", + "core-js": "~3.39.0" + }, + "bin": { + "rsbuild": "bin/rsbuild.js" + }, + "engines": { + "node": ">=16.7.0" + } + }, + "node_modules/@rslib/core": { + "version": "0.2.2", + "resolved": "https://bnpm.byted.org/@rslib/core/-/core-0.2.2.tgz", + "integrity": "sha512-u4qKfoO2YAdtoga6NqCDcTfvqyaTZj/L0kZjDrbThMcD51qUb8HiCS8pX5Hwj5v4doGkk+rHeQnw0Ad7HyMPMQ==", + "dev": true, + "dependencies": { + "@rsbuild/core": "~1.1.13", + "rsbuild-plugin-dts": "0.2.2", + "tinyglobby": "^0.2.10" + }, + "bin": { + "rslib": "bin/rslib.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@rspack/binding": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding/-/binding-1.1.8.tgz", + "integrity": "sha512-+/JzXx1HctfgPj+XtsCTbRkxiaOfAXGZZLEvs7jgp04WgWRSZ5u97WRCePNPvy+sCfOEH/2zw2ZK36Z7oQRGhQ==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.8", + "@rspack/binding-darwin-x64": "1.1.8", + "@rspack/binding-linux-arm64-gnu": "1.1.8", + "@rspack/binding-linux-arm64-musl": "1.1.8", + "@rspack/binding-linux-x64-gnu": "1.1.8", + "@rspack/binding-linux-x64-musl": "1.1.8", + "@rspack/binding-win32-arm64-msvc": "1.1.8", + "@rspack/binding-win32-ia32-msvc": "1.1.8", + "@rspack/binding-win32-x64-msvc": "1.1.8" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.8.tgz", + "integrity": "sha512-I7avr471ghQ3LAqKm2fuXuJPLgQ9gffn5Q4nHi8rsukuZUtiLDPfYzK1QuupEp2JXRWM1gG5lIbSUOht3cD6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.8.tgz", + "integrity": "sha512-vfqf/c+mcx8rr1M8LnqKmzDdnrgguflZnjGerBLjNerAc+dcUp3lCvNxRIvZ2TkSZZBW8BpCMgjj3n70CZ4VLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.8.tgz", + "integrity": "sha512-lZlO/rAJSeozi+qtVLkGSXfe+riPawCwM4FsrflELfNlvvEXpANwtrdJ+LsaNVXcgvhh50ZX2KicTdmx9G2b6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.8.tgz", + "integrity": "sha512-bX7exULSZwy8xtDh6Z65b6sRC4uSxGuyvSLCEKyhmG6AnJkg0gQMxk3hoO0hWnyGEZgdJEn+jEhk0fjl+6ZRAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.8.tgz", + "integrity": "sha512-2Prw2USgTJ3aLdLExfik8pAwAHbX4MZrACBGEmR7Vbb56kLjC+++fXkciRc50pUDK4JFr1VQ7eNZrJuDR6GG6Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.8.tgz", + "integrity": "sha512-bnVGB/mQBKEdzOU/CPmcOE3qEXxGOGGW7/i6iLl2MamVOykJq8fYjL9j86yi6L0r009ja16OgWckykQGc4UqGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.8.tgz", + "integrity": "sha512-u+na3gxhzeksm4xZyAzn1+XWo5a5j7hgWA/KcFPDQ8qQNkRknx4jnQMxVtcZ9pLskAYV4AcOV/AIximx7zvv8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.8.tgz", + "integrity": "sha512-FijUxym1INd5fFHwVCLuVP8XEAb4Sk1sMwEEQUlugiDra9ZsLaPw4OgPGxbxkD6SB0DeUz9Zq46Xbcf6d3OgfA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.8.tgz", + "integrity": "sha512-SBzIcND4qpDt71jlu1MCDxt335tqInT3YID9V4DoQ4t8wgM/uad7EgKOWKTK6vc2RRaOIShfS2XzqjNUxPXh4w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.1.8", + "resolved": "https://bnpm.byted.org/@rspack/core/-/core-1.1.8.tgz", + "integrity": "sha512-pcZtcj5iXLCuw9oElTYC47bp/RQADm/MMEb3djHdwJuSlFWfWPQi5QFgJ/lJAxIW9UNHnTFrYtytycfjpuoEcA==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.8", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://bnpm.byted.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://bnpm.byted.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://bnpm.byted.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://bnpm.byted.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://bnpm.byted.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/core-js": { + "version": "3.39.0", + "resolved": "https://bnpm.byted.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://bnpm.byted.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://bnpm.byted.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://bnpm.byted.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fetch-cookie": { + "version": "3.1.0", + "resolved": "https://bnpm.byted.org/fetch-cookie/-/fetch-cookie-3.1.0.tgz", + "integrity": "sha512-s/XhhreJpqH0ftkGVcQt8JE9bqk+zRn4jF5mPJXWZeQMCI5odV9K+wEWYbnzFPHgQZlvPSMjS4n4yawWE8RINw==", + "dev": true, + "dependencies": { + "set-cookie-parser": "^2.4.8", + "tough-cookie": "^5.0.0" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://bnpm.byted.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://bnpm.byted.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://bnpm.byted.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://bnpm.byted.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://bnpm.byted.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://bnpm.byted.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://bnpm.byted.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rsbuild-plugin-dts": { + "version": "0.2.2", + "resolved": "https://bnpm.byted.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.2.2.tgz", + "integrity": "sha512-RwkVcMwig1+UHkVJFaD6tagjxZOQqIenbkLS+J85bEdKO/ra+YiLC1Gq3DItEv/hU02u5WPgJmQhaQWKb17T9w==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.17", + "picocolors": "1.1.1", + "tinyglobby": "^0.2.10" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7", + "@rsbuild/core": "1.x", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://bnpm.byted.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "dev": true + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://bnpm.byted.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.70", + "resolved": "https://bnpm.byted.org/tldts/-/tldts-6.1.70.tgz", + "integrity": "sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==", + "dev": true, + "dependencies": { + "tldts-core": "^6.1.70" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.70", + "resolved": "https://bnpm.byted.org/tldts-core/-/tldts-core-6.1.70.tgz", + "integrity": "sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "5.0.0", + "resolved": "https://bnpm.byted.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", + "dev": true, + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://bnpm.byted.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true }, "node_modules/typescript": { "version": "5.6.3", @@ -32,6 +719,21 @@ "engines": { "node": ">=14.17" } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://bnpm.byted.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://bnpm.byted.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } } } } diff --git a/package.json b/package.json index 61c084c..e9ba20b 100644 --- a/package.json +++ b/package.json @@ -1,35 +1,68 @@ { - "name": "@nsnanocat/util", - "description": "Pure JS's util module for well-known iOS network tools", - "author": "VirgilClyne ", - "homepage": "https://NSNanoCat.github.io/util", - "keywords": [ - "loon", - "quantumult", - "surge", - "shadowrocket", - "stash", - "egern" - ], - "license": "Apache-2.0", - "bugs": "https://github.com/NSNanoCat/util/issues", - "main": "index.js", - "type": "module", - "scripts": { - "tsc:build": "npx tsc", - "test": "exit 0" - }, - "repository": { - "type": "git", - "url": "https://github.com/NSNanoCat/util.git" - }, - "files": [ - "index.js", - "lib", - "polyfill", - "getStorage.mjs" - ], - "devDependencies": { - "typescript": "^5.6.3" - } + "name": "@nsnanocat/util", + "description": "Pure JS's util module for well-known iOS network tools", + "type": "module", + "author": "VirgilClyne ", + "homepage": "https://NSNanoCat.github.io/util", + "keywords": [ + "loon", + "quantumult", + "surge", + "shadowrocket", + "stash", + "egern" + ], + "license": "Apache-2.0", + "bugs": "https://github.com/NSNanoCat/util/issues", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./getStorage": { + "types": "./dist/getStorage.d.ts", + "import": "./dist/getStorage.js", + "require": "./dist/getStorage.cjs" + }, + "./polyfill/**": { + "types": "./dist/polyfill/**.d.ts", + "import": "./dist/polyfill/**.js", + "require": "./dist/polyfill/**.cjs" + }, + "./lib/**": { + "types": "./dist/lib/**.d.ts", + "import": "./dist/lib/**.js", + "require": "./dist/lib/**.cjs" + } + }, + "scripts": { + "build": "rslib build" + }, + "repository": { + "type": "git", + "url": "https://github.com/NSNanoCat/util.git" + }, + "files": [ + "dist" + ], + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.2", + "@rslib/core": "^0.2.2", + "@types/lodash": "^4.17.13", + "@types/node": "^22.10.2", + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2", + "typescript": "^5.6.3" + }, + "optionalDependencies": { + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2" + } } diff --git a/polyfill/Console.mjs b/polyfill/Console.mjs deleted file mode 100644 index 9affeb6..0000000 --- a/polyfill/Console.mjs +++ /dev/null @@ -1,175 +0,0 @@ -import { $app } from "../lib/app.mjs"; - -export class Console { - static #counts = new Map([]); - static #groups = []; - static #times = new Map([]); - - static clear = () => {}; - - static count = (label = "default") => { - switch (Console.#counts.has(label)) { - case true: - Console.#counts.set(label, Console.#counts.get(label) + 1); - break; - case false: - Console.#counts.set(label, 0); - break; - } - Console.log(`${label}: ${Console.#counts.get(label)}`); - }; - - static countReset = (label = "default") => { - switch (Console.#counts.has(label)) { - case true: - Console.#counts.set(label, 0); - Console.log(`${label}: ${Console.#counts.get(label)}`); - break; - case false: - Console.warn(`Counter "${label}" doesn’t exist`); - break; - } - }; - - static debug = (...msg) => { - if (Console.#level < 4) return; - msg = msg.map(m => `🅱️ ${m}`); - Console.log(...msg); - }; - - static error(...msg) { - if (Console.#level < 1) return; - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - case "Quantumult X": - default: - msg = msg.map(m => `❌ ${m}`); - break; - case "Node.js": - msg = msg.map(m => `❌ ${m.stack}`); - break; - } - Console.log(...msg); - } - - static exception = (...msg) => Console.error(...msg); - - static group = label => Console.#groups.unshift(label); - - static groupEnd = () => Console.#groups.shift(); - - static info(...msg) { - if (Console.#level < 3) return; - msg = msg.map(m => `ℹ️ ${m}`); - Console.log(...msg); - } - - static #level = 3; - - static get logLevel() { - switch (Console.#level) { - case 0: - return "OFF"; - case 1: - return "ERROR"; - case 2: - return "WARN"; - case 3: - default: - return "INFO"; - case 4: - return "DEBUG"; - case 5: - return "ALL"; - } - } - - static set logLevel(level) { - switch (typeof level) { - case "string": - level = level.toLowerCase(); - break; - case "number": - break; - case "undefined": - default: - level = "warn"; - break; - } - switch (level) { - case 0: - case "off": - Console.#level = 0; - break; - case 1: - case "error": - Console.#level = 1; - break; - case 2: - case "warn": - case "warning": - default: - Console.#level = 2; - break; - case 3: - case "info": - Console.#level = 3; - break; - case 4: - case "debug": - Console.#level = 4; - break; - case 5: - case "all": - Console.#level = 5; - break; - } - } - - static log = (...msg) => { - if (Console.#level === 0) return; - msg = msg.map(log => { - switch (typeof log) { - case "object": - log = JSON.stringify(log); - break; - case "bigint": - case "number": - case "boolean": - case "string": - log = log.toString(); - break; - case "undefined": - default: - break; - } - return log; - }); - Console.#groups.forEach(group => { - msg = msg.map(log => ` ${log}`); - msg.unshift(`▼ ${group}:`); - }); - msg = ["", ...msg]; - console.log(msg.join("\n")); - }; - - static time = (label = "default") => Console.#times.set(label, Date.now()); - - static timeEnd = (label = "default") => Console.#times.delete(label); - - static timeLog = (label = "default") => { - const time = Console.#times.get(label); - if (time) Console.log(`${label}: ${Date.now() - time}ms`); - else Console.warn(`Timer "${label}" doesn’t exist`); - }; - - static warn(...msg) { - if (Console.#level < 2) return; - msg = msg.map(m => `⚠️ ${m}`); - Console.log(...msg); - } -} diff --git a/polyfill/Lodash.mjs b/polyfill/Lodash.mjs deleted file mode 100644 index 1e2f71e..0000000 --- a/polyfill/Lodash.mjs +++ /dev/null @@ -1,72 +0,0 @@ -/* https://www.lodashjs.com */ -export class Lodash { - static escape(string) { - const map = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - }; - return string.replace(/[&<>"']/g, m => map[m]); - } - - static get(object = {}, path = "", defaultValue = undefined) { - // translate array case to dot case, then split with . - // a[0].b -> a.0.b -> ['a', '0', 'b'] - if (!Array.isArray(path)) path = Lodash.toPath(path); - - const result = path.reduce((previousValue, currentValue) => { - return Object(previousValue)[currentValue]; // null undefined get attribute will throwError, Object() can return a object - }, object); - return result === undefined ? defaultValue : result; - } - - static omit(object = {}, paths = []) { - if (!Array.isArray(paths)) paths = [paths.toString()]; - paths.forEach(path => Lodash.unset(object, path)); - return object; - } - - static pick(object = {}, paths = []) { - if (!Array.isArray(paths)) paths = [paths.toString()]; - const filteredEntries = Object.entries(object).filter(([key, value]) => paths.includes(key)); - return Object.fromEntries(filteredEntries); - } - - static set(object, path, value) { - if (!Array.isArray(path)) path = Lodash.toPath(path); - path.slice(0, -1).reduce((previousValue, currentValue, currentIndex) => (Object(previousValue[currentValue]) === previousValue[currentValue] ? previousValue[currentValue] : (previousValue[currentValue] = /^\d+$/.test(path[currentIndex + 1]) ? [] : {})), object)[path[path.length - 1]] = value; - return object; - } - - static toPath(value) { - return value - .replace(/\[(\d+)\]/g, ".$1") - .split(".") - .filter(Boolean); - } - - static unescape(string) { - const map = { - "&": "&", - "<": "<", - ">": ">", - """: '"', - "'": "'", - }; - return string.replace(/&|<|>|"|'/g, m => map[m]); - } - - static unset(object = {}, path = "") { - if (!Array.isArray(path)) path = Lodash.toPath(path); - const result = path.reduce((previousValue, currentValue, currentIndex) => { - if (currentIndex === path.length - 1) { - delete previousValue[currentValue]; - return true; - } - return Object(previousValue)[currentValue]; - }, object); - return result; - } -} diff --git a/polyfill/Storage.mjs b/polyfill/Storage.mjs deleted file mode 100644 index 116d70a..0000000 --- a/polyfill/Storage.mjs +++ /dev/null @@ -1,257 +0,0 @@ -import { $app } from "../lib/app.mjs"; -import { Lodash as _ } from "./Lodash.mjs"; - -/** - * Storage - * - * @link https://developer.mozilla.org/zh-CN/docs/Web/API/Storage/setItem - * @export - * @class Storage - * @typedef {Storage} - */ -export class Storage { - /** - * data - * - * @static - * @type {file} - */ - static data = null; - static dataFile = "box.dat"; - /** - * nameRegex - * - * @static - * @type {regexp} - */ - static #nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; - - /** - * getItem - * - * @static - * @param {string} keyName - * @param {*} [defaultValue] - * @returns {*} - */ - static getItem(keyName, defaultValue = null) { - let keyValue = defaultValue; - // 如果以 @ - switch (keyName.startsWith("@")) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName, {}); - if (typeof value !== "object") value = {}; - keyValue = _.get(value, path); - try { - keyValue = JSON.parse(keyValue); - } catch (e) {} - break; - } - default: - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - keyValue = $persistentStore.read(keyName); - break; - case "Quantumult X": - keyValue = $prefs.valueForKey(keyName); - break; - case "Node.js": - Storage.data = Storage.#loaddata(Storage.dataFile); - keyValue = Storage.data?.[keyName]; - break; - default: - keyValue = Storage.data?.[keyName] || null; - break; - } - try { - keyValue = JSON.parse(keyValue); - } catch (e) { - // do nothing - } - break; - } - return keyValue ?? defaultValue; - } - - /** - * setItem - * - * @static - * @param {string} keyName - * @param {*} keyValue - * @returns {boolean} - */ - static setItem(keyName = new String(), keyValue = new String()) { - let result = false; - switch (typeof keyValue) { - case "object": - keyValue = JSON.stringify(keyValue); - break; - default: - keyValue = String(keyValue); - break; - } - switch (keyName.startsWith("@")) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName, {}); - if (typeof value !== "object") value = {}; - _.set(value, path, keyValue); - result = Storage.setItem(keyName, value); - break; - } - default: - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - result = $persistentStore.write(keyValue, keyName); - break; - case "Quantumult X": - result = $prefs.setValueForKey(keyValue, keyName); - break; - case "Node.js": - Storage.data = Storage.#loaddata(Storage.dataFile); - Storage.data[keyName] = keyValue; - Storage.#writedata(Storage.dataFile); - result = true; - break; - default: - result = Storage.data?.[keyName] || null; - break; - } - break; - } - return result; - } - - /** - * removeItem - * - * @static - * @param {string} keyName - * @returns {boolean} - */ - static removeItem(keyName) { - let result = false; - switch (keyName.startsWith("@")) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName); - if (typeof value !== "object") value = {}; - keyValue = _.unset(value, path); - result = Storage.setItem(keyName, value); - break; - } - default: - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - result = false; - break; - case "Quantumult X": - result = $prefs.removeValueForKey(keyName); - break; - case "Node.js": - result = false; - break; - default: - result = false; - break; - } - break; - } - return result; - } - - /** - * clear - * - * @static - * @returns {boolean} - */ - static clear() { - let result = false; - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - result = false; - break; - case "Quantumult X": - result = $prefs.removeAllValues(); - break; - case "Node.js": - result = false; - break; - default: - result = false; - break; - } - return result; - } - - /** - * #loaddata - * - * @param {string} dataFile - * @returns {*} - */ - static #loaddata = dataFile => { - if ($app === "Node.js") { - this.fs = this.fs ? this.fs : require("node:fs"); - this.path = this.path ? this.path : require("node:path"); - const curDirDataFilePath = this.path.resolve(dataFile); - const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); - const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); - const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); - if (isCurDirDataFile || isRootDirDataFile) { - const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath; - try { - return JSON.parse(this.fs.readFileSync(datPath)); - } catch (e) { - return {}; - } - } else return {}; - } else return {}; - }; - - /** - * #writedata - * - * @param {string} [dataFile=this.dataFile] - */ - static #writedata = (dataFile = this.dataFile) => { - if ($app === "Node.js") { - this.fs = this.fs ? this.fs : require("node:fs"); - this.path = this.path ? this.path : require("node:path"); - const curDirDataFilePath = this.path.resolve(dataFile); - const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); - const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); - const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); - const jsondata = JSON.stringify(this.data); - if (isCurDirDataFile) { - this.fs.writeFileSync(curDirDataFilePath, jsondata); - } else if (isRootDirDataFile) { - this.fs.writeFileSync(rootDirDataFilePath, jsondata); - } else { - this.fs.writeFileSync(curDirDataFilePath, jsondata); - } - } - }; -} diff --git a/polyfill/fetch.mjs b/polyfill/fetch.mjs deleted file mode 100644 index 57fa70f..0000000 --- a/polyfill/fetch.mjs +++ /dev/null @@ -1,202 +0,0 @@ -import { $app } from "../lib/app.mjs"; -import { Console } from "./Console.mjs"; -import { Lodash as _ } from "./Lodash.mjs"; -import { StatusTexts } from "./StatusTexts.mjs"; - -/** - * fetch - * - * @link https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API - * @export - * @async - * @param {object|string} resource - * @param {object} [options] - * @returns {Promise} - */ -export async function fetch(resource, options = {}) { - // 初始化参数 - switch (typeof resource) { - case "object": - resource = { ...options, ...resource }; - break; - case "string": - resource = { ...options, url: resource }; - break; - case "undefined": - default: - throw new TypeError(`${Function.name}: 参数类型错误, resource 必须为对象或字符串`); - } - // 自动判断请求方法 - if (!resource.method) { - resource.method = "GET"; - if (resource.body ?? resource.bodyBytes) resource.method = "POST"; - } - // 移除请求头中的部分参数, 让其自动生成 - delete resource.headers?.Host; - delete resource.headers?.[":authority"]; - delete resource.headers?.["Content-Length"]; - delete resource.headers?.["content-length"]; - // 定义请求方法(小写) - const method = resource.method.toLocaleLowerCase(); - // 转换请求超时时间参数 - if (!resource.timeout) resource.timeout = 5; - if (resource.timeout) { - resource.timeout = Number.parseInt(resource.timeout, 10); - // 转换为秒,大于500视为毫秒,小于等于500视为秒 - if (resource.timeout > 500) resource.timeout = Math.round(resource.timeout / 1000); - } - // 判断平台 - switch ($app) { - case "Loon": - case "Surge": - case "Stash": - case "Egern": - case "Shadowrocket": - default: - // 转换请求参数 - if (resource.timeout) { - switch ($app) { - case "Loon": - resource.timeout = resource.timeout * 1000; - break; - case "Shadowrocket": - case "Stash": - case "Egern": - case "Surge": - default: - break; - } - } - if (resource.policy) { - switch ($app) { - case "Loon": - resource.node = resource.policy; - break; - case "Stash": - _.set(resource, "headers.X-Stash-Selected-Proxy", encodeURI(resource.policy)); - break; - case "Shadowrocket": - _.set(resource, "headers.X-Surge-Proxy", resource.policy); - break; - } - } - if (typeof resource.redirection === "boolean") resource["auto-redirect"] = resource.redirection; - // 转换请求体 - if (resource.bodyBytes && !resource.body) { - resource.body = resource.bodyBytes; - resource.bodyBytes = undefined; - } - // 判断是否请求二进制响应体 - switch ((resource.headers?.Accept || resource.headers?.accept)?.split(";")?.[0]) { - case "application/protobuf": - case "application/x-protobuf": - case "application/vnd.google.protobuf": - case "application/vnd.apple.flatbuffer": - case "application/grpc": - case "application/grpc+proto": - case "application/octet-stream": - resource["binary-mode"] = true; - break; - } - // 发送请求 - return await new Promise((resolve, reject) => { - $httpClient[method](resource, (error, response, body) => { - if (error) reject(error); - else { - response.ok = /^2\d\d$/.test(response.status); - response.statusCode = response.status; - response.statusText = StatusTexts[response.status]; - if (body) { - response.body = body; - if (resource["binary-mode"] == true) response.bodyBytes = body; - } - resolve(response); - } - }); - }); - case "Quantumult X": - // 转换请求参数 - if (resource.policy) _.set(resource, "opts.policy", resource.policy); - if (typeof resource["auto-redirect"] === "boolean") _.set(resource, "opts.redirection", resource["auto-redirect"]); - // 转换请求体 - if (resource.body instanceof ArrayBuffer) { - resource.bodyBytes = resource.body; - resource.body = undefined; - } else if (ArrayBuffer.isView(resource.body)) { - resource.bodyBytes = resource.body.buffer.slice(resource.body.byteOffset, resource.body.byteLength + resource.body.byteOffset); - resource.body = undefined; - } else if (resource.body) resource.bodyBytes = undefined; - // 发送请求 - return Promise.race([ - await $task.fetch(resource).then( - response => { - response.ok = /^2\d\d$/.test(response.statusCode); - response.status = response.statusCode; - response.statusText = StatusTexts[response.status]; - switch ((response.headers?.["Content-Type"] ?? response.headers?.["content-type"])?.split(";")?.[0]) { - case "application/protobuf": - case "application/x-protobuf": - case "application/vnd.google.protobuf": - case "application/vnd.apple.flatbuffer": - case "application/grpc": - case "application/grpc+proto": - case "application/octet-stream": - response.body = response.bodyBytes; - break; - case undefined: - default: - break; - } - response.bodyBytes = undefined; - return response; - }, - reason => Promise.reject(reason.error), - ), - new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); - }, resource.timeout); - }), - ]); - case "Node.js": { - const nodeFetch = globalThis.fetch ? globalThis.fetch : require("node-fetch"); - const fetchCookie = globalThis.fetchCookie ? globalThis.fetchCookie : require("fetch-cookie").default; - const fetch = fetchCookie(nodeFetch); - // 转换请求参数 - resource.timeout = resource.timeout * 1000; - resource.redirect = resource.redirection ? "follow" : "manual"; - const { url, ...options } = resource; - // 发送请求 - return Promise.race([ - await fetch(url, options) - .then(async response => { - const bodyBytes = await response.arrayBuffer(); - let headers; - try { - headers = response.headers.raw(); - } catch { - headers = Array.from(response.headers.entries()).reduce((acc, [key, value]) => { - acc[key] = acc[key] ? [...acc[key], value] : [value]; - return acc; - }, {}); - } - return { - ok: response.ok ?? /^2\d\d$/.test(response.status), - status: response.status, - statusCode: response.status, - statusText: response.statusText, - body: new TextDecoder("utf-8").decode(bodyBytes), - bodyBytes: bodyBytes, - headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, key.toLowerCase() !== "set-cookie" ? value.toString() : value])), - }; - }) - .catch(error => Promise.reject(error.message)), - new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); - }, resource.timeout); - }), - ]); - } - } -} diff --git a/polyfill/index.js b/polyfill/index.js deleted file mode 100644 index a4dc2d5..0000000 --- a/polyfill/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./Console.mjs"; -export * from "./fetch.mjs"; -export * from "./Lodash.mjs"; -export * from "./StatusTexts.mjs"; -export * from "./Storage.mjs"; diff --git a/rslib.config.ts b/rslib.config.ts new file mode 100644 index 0000000..cf60c55 --- /dev/null +++ b/rslib.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { format: 'esm', syntax: 'es2021', bundle: false, dts: true, }, + { format: 'cjs', syntax: 'es2021', bundle: false }, + ], + source: { + entry: { + index: './src/**' + }, + transformImport: [ + { + libraryName: 'lodash', + customName: 'lodash/{{ member }}', + }, + ] + } +}); \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..e87d9a5 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,11 @@ +interface Environment { + "loon-version"?: string; + 'surge-version'?: string; + 'stash-version'?: string; +} + +// biome-ignore lint/suspicious/useNamespaceKeyword: This is a global declaration file +declare module globalThis { + // biome-ignore lint/style/noVar: This is a global declaration file + var $environment: Environment +} \ No newline at end of file diff --git a/src/getStorage.ts b/src/getStorage.ts new file mode 100644 index 0000000..0aac517 --- /dev/null +++ b/src/getStorage.ts @@ -0,0 +1,109 @@ +import { set } from "lodash"; +import { Storage } from "./polyfill/Storage"; + +type Database = Record; + +interface StoreType< + Settings extends Record = Record, + Configs extends Record = Record, + Caches extends Record = Record, +> { + Settings: Settings; + Configs: Configs; + Caches: Caches; +} + +declare const $argument: string | object + +export function getStorage = Record, + Configs extends Record = Record, + Caches extends Record = Record,>(key: string, names: string | string[], database: Database): StoreType { + const nameList = Array.isArray(names) ? names : [names]; + + const Store = { + Settings: database?.Default?.Settings || {}, + Configs: database?.Default?.Configs || {}, + Caches: {}, + } as StoreType; + + nameList.forEach((name) => { + Store.Settings = { ...Store.Settings, ...database?.[name]?.Settings }; + Store.Configs = { ...Store.Configs, ...database?.[name]?.Configs }; + }); + + if (typeof $argument === "string") { + const parsedArgument = Object.fromEntries( + $argument.split("&").map((item) => item.split("=", 2).map((i) => i.replace(/\"/g, ""))) + ); + Object.keys(parsedArgument).forEach((key) => set(Store.Settings, key, parsedArgument[key])); + } else if (typeof $argument === "object") { + Object.keys($argument).forEach((key) => set(Store.Settings, key, $argument[key as keyof typeof $argument])); + } + + /***************** BoxJs *****************/ + // 包装为局部变量,用完释放内存 + // BoxJs的清空操作返回假值空字符串, 逻辑或操作符会在左侧操作数为假值时返回右侧操作数。 + const BoxJs = Storage.getItem(key); + if (BoxJs) { + //Console.debug("BoxJs", `BoxJs类型: ${typeof BoxJs}`, `BoxJs内容: ${JSON.stringify(BoxJs || {})}`); + nameList.forEach(name => { + const boxSettings = BoxJs?.[name]?.Settings; + const boxCaches = BoxJs?.[name]?.Caches; + + if (typeof boxSettings === "string") { + BoxJs[name].Settings = JSON.parse(boxSettings || "{}"); + } + if (boxSettings) { + Store.Settings = { ...Store.Settings, ...BoxJs[name].Settings }; + } + + if (typeof boxCaches === "string") { + BoxJs[name].Caches = JSON.parse(boxCaches || "{}"); + } + if (boxCaches) { + Store.Caches = { ...Store.Caches, ...BoxJs[name].Caches }; + } + }); + } + + /***************** traverseObject *****************/ + traverseObject(Store.Settings, (key, value) => { + //Console.debug("☑️ traverseObject", `${key}: ${typeof value}`, `${key}: ${JSON.stringify(value)}`); + let transformedValue = value; + if (transformedValue === "true" || transformedValue === "false") + transformedValue = JSON.parse(transformedValue); // 字符串转Boolean + else if (typeof transformedValue === "string") { + if (transformedValue.includes(",")) + transformedValue = transformedValue.split(",").map(item => string2number(item)); // 字符串转数组转数字 + else transformedValue = string2number(transformedValue); // 字符串转数字 + } + return transformedValue; + }); + + return Store; +} + + +/** + * Recursively traverse and transform object properties. + */ +function traverseObject( + obj: Record, + callback: (key: string, value: any) => any +): Record { + Object.entries(obj).forEach(([key, value]) => { + if (value && typeof value === "object") { + obj[key] = traverseObject(value, callback); + } else { + obj[key] = callback(key, value); + } + }); + return obj; +} + +/** + * Convert string to number if applicable. + */ +function string2number(value: string): number | string { + return /^\d+$/.test(value) ? Number(value) : value; +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..968edd0 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,11 @@ +export * from "./lib/app"; +export * from "./lib/done"; +export * from "./lib/notification"; +export * from "./lib/time"; +export * from "./lib/wait"; +export * from "./polyfill/Console"; +export * from "./polyfill/fetch"; +export * from "./polyfill/Lodash"; +export * from "./polyfill/StatusTexts"; +export * from "./polyfill/Storage"; +export * from "./getStorage"; diff --git a/src/lib/app.ts b/src/lib/app.ts new file mode 100644 index 0000000..15c0b19 --- /dev/null +++ b/src/lib/app.ts @@ -0,0 +1,28 @@ +/** + * Current app name + */ +export const $app = (() => { + if ("$task" in globalThis) { + return "Quantumult X"; + } + if ("$loon" in globalThis) { + return "Loon"; + } + if ("$rocket" in globalThis) { + return "Shadowrocket"; + } + if ("Egern" in globalThis) { + return "Egern"; + } + if ("$environment" in globalThis) { + if (globalThis.$environment["surge-version"]) { + return "Surge"; + } + if (globalThis.$environment["stash-version"]) { + return "Stash"; + } + } + if (typeof module !== "undefined") { + return "Node.js"; + } +})(); diff --git a/src/lib/done.ts b/src/lib/done.ts new file mode 100644 index 0000000..796bdc5 --- /dev/null +++ b/src/lib/done.ts @@ -0,0 +1,115 @@ +import { $app } from './app'; +import { Console } from '../polyfill/Console'; +import { StatusTexts } from '../polyfill/StatusTexts'; +import { pick, set } from 'lodash'; + +interface DoneObject { + status?: number | string; + url?: string; + headers?: Record; + body?: ArrayBuffer | ArrayBufferView | string; + bodyBytes?: ArrayBuffer; + policy?: string; + node?: string; + opts?: { + policy?: string; + }; +} + +declare const $done: (object: DoneObject) => void; +declare const $script: { + startTime: number; +}; + +const transformQuantumultXBody = (object: DoneObject): Partial => { + if (object.body instanceof ArrayBuffer) { + return { bodyBytes: object.body, body: undefined }; + } + if (ArrayBuffer.isView(object.body)) { + return { + bodyBytes: object.body.buffer.slice(object.body.byteOffset, object.body.byteOffset + object.body.byteLength), + body: undefined, + }; + } + return { bodyBytes: undefined }; +}; + +const transformQuantumultXStatus = (object: DoneObject): Partial => { + if (typeof object.status === 'number') { + return { + status: `HTTP/1.1 ${object.status} ${StatusTexts[object.status as keyof typeof StatusTexts]}`, + }; + } + if (typeof object.status !== 'string' && object.status !== undefined) { + throw new TypeError(`${done.name}: 参数类型错误, status 必须为数字或字符串`); + } + return {}; +}; + +const handleDoneFactory = (startTime?: number) => { + return (result: DoneObject) => { + Console.log('🚩 执行结束!', startTime ? `🕛 ${((Date.now() - startTime) / 1000).toFixed(3)} 秒` : undefined); + $done(result); + } +} + + +/** + * Complete the script execution + */ +export function done(object: DoneObject = {}): void { + let startTime = $script?.startTime; + if ($app === 'Surge') { + startTime *= 1000; + } + + const handleDone = handleDoneFactory(startTime); + + switch ($app) { + case 'Surge': + if (object.policy) { + set(object, 'headers.X-Surge-Policy', object.policy); + } + handleDone(object); + break; + + case 'Loon': + if (object.policy) { + object.node = object.policy; + } + handleDone(object); + break; + + case 'Stash': + if (object.policy) { + set(object, 'headers.X-Stash-Selected-Proxy', encodeURI(object.policy)); + } + handleDone(object); + break; + + case 'Egern': + handleDone(object); + break; + + case 'Shadowrocket': + handleDone(object); + break; + + case 'Quantumult X': { + const transformedObject = { + ...pick(object, ['status', 'url', 'headers', 'body', 'bodyBytes']), + ...transformQuantumultXStatus(object), + ...transformQuantumultXBody(object), + }; + if (object.policy) { + set(transformedObject, 'opts.policy', object.policy); + } + handleDone(transformedObject); + break; + } + case 'Node.js': + default: + Console.log("🚩 执行结束!"); + process.exit(1); + } +} diff --git a/lib/environment.mjs b/src/lib/environment.ts similarity index 57% rename from lib/environment.mjs rename to src/lib/environment.ts index 5b70418..aa45e6c 100644 --- a/lib/environment.mjs +++ b/src/lib/environment.ts @@ -1,7 +1,16 @@ -import { $app } from "./app.mjs"; +import { $app } from "./app"; -export const $environment = environment(); -export function environment() { +interface Environment extends globalThis.Environment { + app?: string; + device?: string; + ios?: string; + [key: string]: string | undefined; +} + +declare const $loon: string; +declare const $environment: Environment; + +export function environment(): Environment { switch ($app) { case "Surge": $environment.app = "Surge"; @@ -26,9 +35,13 @@ export function environment() { app: "Quantumult X", }; case "Node.js": - process.env.app = "Node.js"; - return process.env; + return { + ...process.env, + app: "Node.js", + }; default: return {}; } } + +// export const $environment = environment(); diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..ebb0110 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1,5 @@ +export * from "./app"; +export * from "./done"; +export * from "./notification"; +export * from "./time"; +export * from "./wait"; diff --git a/src/lib/notification.ts b/src/lib/notification.ts new file mode 100644 index 0000000..00272b0 --- /dev/null +++ b/src/lib/notification.ts @@ -0,0 +1,152 @@ +import { $app } from "./app.js"; +import { Console } from "../polyfill/Console.js"; + +interface NotificationContent { + open?: string; + "open-url"?: string; + url?: string; + openUrl?: string; + copy?: string; + "update-pasteboard"?: string; + updatePasteboard?: string; + media?: string; + "media-url"?: string; + mediaUrl?: string; + "auto-dismiss"?: boolean; + sound?: string; + mime?: string; +} + +declare const $notify: (title: string, subtitle: string, body: string, content: NotificationContent) => void; +declare const $notification: { + post: (title: string, subtitle: string, body: string, content: NotificationContent) => void; +}; + +/** + * 系统通知 + */ +export function notification( + title = `ℹ️ ${$app} 通知`, + subtitle = "", + body = "", + content: string | number | boolean | NotificationContent = {} +): void { + const mutableContent = getMutableContent(content); + + switch ($app) { + case "Quantumult X": + $notify(title, subtitle, body, mutableContent); + break; + case "Node.js": + break; + default: + $notification.post(title, subtitle, body, mutableContent); + break; + } + Console.group("📣 系统通知"); + Console.log(title, subtitle, body, JSON.stringify(mutableContent, null, 2)); + Console.groupEnd(); +} + +function getMutableContent(content: string | number | boolean | NotificationContent): Record { + const mutableContent: Record = {}; + + switch (typeof content) { + case "string": + case "number": + case "boolean": + assignSimpleContent(mutableContent, content); + break; + + case "object": + if (content) { + assignObjectContent(mutableContent, content); + } + break; + + default: + Console.error(`不支持的通知参数类型: ${typeof content}`); + break; + } + + return mutableContent; +} + +function assignSimpleContent(mutableContent: Record, content: string | number | boolean): void { + switch ($app) { + case "Quantumult X": + mutableContent["open-url"] = content; + break; + case "Loon": + case "Shadowrocket": + mutableContent.openUrl = content; + break; + default: + mutableContent.url = content; + break; + } +} + +function assignObjectContent(mutableContent: Record, content: NotificationContent): void { + const openUrl = content.open || content["open-url"] || content.url || content.openUrl; + const copyUrl = content.copy || content["update-pasteboard"] || content.updatePasteboard; + const mediaUrl = content.media || content["media-url"] || content.mediaUrl; + + switch ($app) { + case "Quantumult X": + if (openUrl) mutableContent["open-url"] = openUrl; + if (mediaUrl?.startsWith("http")) mutableContent["media-url"] = mediaUrl; + if (copyUrl) mutableContent["update-pasteboard"] = copyUrl; + break; + + case "Loon": + if (openUrl) mutableContent.openUrl = openUrl; + if (mediaUrl?.startsWith("http")) mutableContent.mediaUrl = mediaUrl; + break; + + default: + if (openUrl) { + mutableContent.action = "open-url"; + mutableContent.url = openUrl; + } + if (copyUrl) { + mutableContent.action = "clipboard"; + mutableContent.text = copyUrl; + } + if (mediaUrl) { + handleMediaContent(mutableContent, mediaUrl, content.mime); + } + if (content["auto-dismiss"]) mutableContent["auto-dismiss"] = content["auto-dismiss"]; + if (content.sound) mutableContent.sound = content.sound; + break; + } +} + +function handleMediaContent( + mutableContent: Record, + mediaUrl: string, + mime?: string +): void { + if (mediaUrl.startsWith("http")) { + mutableContent["media-url"] = mediaUrl; + } else if (mediaUrl.startsWith("data:")) { + const base64RegExp = /^data:(?\w+\/\w+);base64,(?.+)/; + const match = mediaUrl.match(base64RegExp); + if (match?.groups) { + mutableContent["media-base64"] = match.groups.Base64; + mutableContent["media-base64-mime"] = mime || match.groups.MIME; + } + } else { + mutableContent["media-base64"] = mediaUrl; + mutableContent["media-base64-mime"] = detectMimeType(mediaUrl); + } +} + +function detectMimeType(base64: string): string { + if (base64.startsWith("JVBERi0")) return "application/pdf"; + if (base64.startsWith("R0lGODdh") || base64.startsWith("R0lGODlh")) return "image/gif"; + if (base64.startsWith("iVBORw0KGgo")) return "image/png"; + if (base64.startsWith("/9j/")) return "image/jpeg"; + if (base64.startsWith("Qk02U")) return "image/bmp"; + return "application/octet-stream"; +} \ No newline at end of file diff --git a/src/lib/runScript.ts b/src/lib/runScript.ts new file mode 100644 index 0000000..7cc5222 --- /dev/null +++ b/src/lib/runScript.ts @@ -0,0 +1,49 @@ +import { Console } from '../polyfill/Console'; +import { Storage } from '../polyfill/Storage'; +import { fetch } from '../polyfill/fetch'; + +export async function runScript(script: string, runOpts: { timeout?: number } = {}) { + try { + // 获取 httpapi 配置 + const httpapi = Storage.getItem('@chavy_boxjs_userCfgs.httpapi')?.replace(/\n/g, '')?.trim(); + if (!httpapi) { + throw new Error('httpapi 配置未找到,请检查配置项!'); + } + + // 设置超时时间,优先使用参数传入的值 + const httpapiTimeoutFromConfig = Number.parseInt( + Storage.getItem('@chavy_boxjs_userCfgs.httpapi_timeout') || '20', + 10, + ); + const timeout = runOpts.timeout ?? httpapiTimeoutFromConfig; + + // 解析 httpapi 的地址和密码 + const [password, address] = httpapi.split('@'); + if (!password || !address) { + throw new Error('httpapi 配置格式错误,应为 password@address 格式!'); + } + + // 构建请求对象 + const request = { + url: `http://${address}/v1/scripting/evaluate`, + body: JSON.stringify({ + script_text: script, + mock_type: 'cron', + timeout, + }), + headers: { + 'X-Key': password, + Accept: '*/*', + }, + timeout, + }; + + // 发起请求 + const response = await fetch(request); + return response.body; // 返回响应体 + } catch (error) { + // 捕获错误并打印 + Console.error('运行脚本时发生错误:', (error as Error).message); + throw error; // 如果需要,可以重新抛出错误 + } +} diff --git a/lib/time.mjs b/src/lib/time.ts similarity index 88% rename from lib/time.mjs rename to src/lib/time.ts index 9272670..354dc04 100644 --- a/lib/time.mjs +++ b/src/lib/time.ts @@ -10,7 +10,7 @@ * @param {number} ts 可选: 根据指定时间戳返回格式化日期 * */ -export function time(format, ts) { +export function time(format: string, ts: number): string { const date = ts ? new Date(ts) : new Date(); const Time = { YY: date.getFullYear().toString().substring(3), @@ -23,8 +23,9 @@ export function time(format, ts) { ss: date.getSeconds().toString().padStart(2, "0"), S: `${Math.floor(date.getMonth() / 3) + 1}`, }; + let result = format; for (const [key, value] of Object.entries(Time)) { - format = format.replace(key, value); + result = result.replace(key, value); } - return format; + return result; } diff --git a/src/lib/wait.ts b/src/lib/wait.ts new file mode 100644 index 0000000..1d28c70 --- /dev/null +++ b/src/lib/wait.ts @@ -0,0 +1,6 @@ +/** + * wait + */ +export function wait(delay = 1000) { + return new Promise(resolve => setTimeout(resolve, delay)); +} diff --git a/src/polyfill/Console.ts b/src/polyfill/Console.ts new file mode 100644 index 0000000..7726c64 --- /dev/null +++ b/src/polyfill/Console.ts @@ -0,0 +1,186 @@ +import { $app } from "../lib/app"; + +class ConsoleFactory { + #counts = new Map([]); + #groups: string[] = []; + #times = new Map([]); + + clear = () => { }; + + count = (label = "default") => { + if (this.#counts.has(label)) { + this.#counts.set(label, this.#counts.get(label) ?? 0 + 1); + } else { + this.#counts.set(label, 0); + } + this.log(`${label}: ${this.#counts.get(label)}`); + }; + + countReset = (label = "default") => { + switch (this.#counts.has(label)) { + case true: + this.#counts.set(label, 0); + this.log(`${label}: ${this.#counts.get(label)}`); + break; + case false: + this.warn(`Counter "${label}" doesn’t exist`); + break; + } + }; + + debug = (...args: any[]) => { + if (this.#level < 4) return; + this.log(...args.map((m) => `🅱️ ${m}`)); + }; + + error(...msg: any[]) { + if (this.#level < 1) return; + switch ($app) { + case "Surge": + case "Loon": + case "Stash": + case "Egern": + case "Shadowrocket": + case "Quantumult X": + case "Node.js": + this.log(...msg.map((m) => { + if (m instanceof Error) { + return `❌ ${m.stack}` + } + return `❌ ${m}` + })); + break; + default: + this.log(...msg.map((m) => `❌ ${m}`)); + break; + } + } + + exception = (...msg: any[]) => this.error(...msg); + + group = (label: string) => this.#groups.unshift(label); + + groupEnd = () => this.#groups.shift(); + + info(...msg: any[]) { + if (this.#level < 3) return; + this.log(...msg.map((m) => `ℹ️ ${m}`)); + } + + #level = 3; + + get logLevel() { + switch (this.#level) { + case 0: + return "OFF"; + case 1: + return "ERROR"; + case 2: + return "WARN"; + case 4: + return "DEBUG"; + case 5: + return "ALL"; + case 3: + default: + return "INFO"; + } + } + + set logLevel(_level: string | number) { + let level = _level; + switch (typeof level) { + case "string": + level = level.toLowerCase(); + break; + case "number": + break; + case "undefined": + default: + level = "warn"; + break; + } + switch (level) { + case 0: + case "off": + this.#level = 0; + break; + case 1: + case "error": + this.#level = 1; + break; + case 3: + case "info": + this.#level = 3; + break; + case 4: + case "debug": + this.#level = 4; + break; + case 5: + case "all": + this.#level = 5; + break; + case 2: + case "warn": + case "warning": + default: + this.#level = 2; + break; + } + } + + log = (...args: any[]) => { + if (this.#level === 0) return; + let msg = args + msg = msg.map((item) => { + let log = item; + switch (typeof log) { + case "object": + log = JSON.stringify(log); + break; + case "bigint": + case "number": + case "boolean": + case "string": + log = log.toString(); + break; + case "undefined": + default: + break; + } + return log; + }); + this.#groups.forEach((group) => { + msg = msg.map((log) => ` ${log}`); + msg.unshift(`▼ ${group}:`); + }); + msg = ["", ...msg]; + console.log(msg.join("\n")); + }; + + time = (label = "default") => this.#times.set(label, Date.now()); + + timeEnd = (label = "default") => this.#times.delete(label); + + timeLog = (label = "default") => { + const time = this.#times.get(label); + if (time) { + this.log(`${label}: ${Date.now() - time}ms`); + } else { + this.warn(`Timer "${label}" doesn’t exist`); + } + }; + + warn(...args: any[]) { + if (this.#level < 2) { + return; + } + let msg = args; + msg = msg.map((m) => `⚠️ ${m}`); + this.log(...msg); + } +} + + +export const Console = new ConsoleFactory(); \ No newline at end of file diff --git a/src/polyfill/Lodash.ts b/src/polyfill/Lodash.ts new file mode 100644 index 0000000..7f13d28 --- /dev/null +++ b/src/polyfill/Lodash.ts @@ -0,0 +1,22 @@ +import { + escape as lodashEscape, + get, + omit, + pick, + set, + toPath, + unescape as lodashUnescape, + unset, +} from 'lodash' + + +export const Lodash = { + escape: lodashEscape, + get, + omit, + pick, + set, + toPath, + unescape: lodashUnescape, + unset, +} diff --git a/polyfill/StatusTexts.mjs b/src/polyfill/StatusTexts.ts similarity index 100% rename from polyfill/StatusTexts.mjs rename to src/polyfill/StatusTexts.ts diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts new file mode 100644 index 0000000..afb602f --- /dev/null +++ b/src/polyfill/Storage.ts @@ -0,0 +1,174 @@ +import { get, set, unset } from "lodash"; +import { $app } from "../lib/app"; + + +declare const $persistentStore: { + read: (key: string) => string | null; + write: (value: string, key: string) => boolean; +} + +declare const $prefs: { + valueForKey: (key: string) => string | null; + setValueForKey: (value: string, key: string) => boolean; + removeValueForKey: (key: string) => boolean; + removeAllValues: () => boolean; +} + +interface StorageData { + [key: string]: any; +} + +export class StorageClass { + private data: StorageData | null = null; + private readonly dataFile: string = "box.dat"; + private readonly nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; + + constructor() { + if ($app === "Node.js") { + const fs = require("node:fs"); + const path = require("node:path"); + this.data = this.#loadData(this.dataFile, fs, path); + } + } + + public getItem(keyName: string, defaultValue = null as T): T { + let keyValue = defaultValue; + + if (keyName.startsWith("@")) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== "object") { + value = {}; + } + keyValue = get(value, path); + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + } else { + switch ($app) { + case "Surge": + case "Loon": + case "Stash": + case "Egern": + case "Shadowrocket": + keyValue = $persistentStore.read(keyName) as T; + break; + case "Quantumult X": + keyValue = $prefs.valueForKey(keyName) as T; + break; + case "Node.js": + this.data = this.data || {}; + keyValue = this.data[keyName]; + break; + default: + keyValue = null as T; + break; + } + + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + + return keyValue ?? defaultValue; + } + + public setItem(keyName: string, value: any): boolean { + let keyValue = value; + if (typeof keyValue === "object") { + keyValue = JSON.stringify(keyValue); + } else { + keyValue = String(keyValue); + } + + if (keyName.startsWith("@")) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== "object") value = {}; + set(value, path, keyValue); + return this.setItem(keyName, value); + } + } else { + switch ($app) { + case "Surge": + case "Loon": + case "Stash": + case "Egern": + case "Shadowrocket": + return $persistentStore.write(keyValue, keyName); + case "Quantumult X": + return $prefs.setValueForKey(keyValue, keyName); + case "Node.js": + this.data = this.data || {}; + this.data[keyName] = keyValue; + this.#writeData(this.dataFile); + return true; + default: + return false; + } + } + + return false; + } + + public removeItem(keyName: string): boolean { + if (keyName.startsWith("@")) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key); + if (typeof value !== "object") value = {}; + unset(value, path); + return this.setItem(key, value); + } + } else { + switch ($app) { + case "Quantumult X": + return $prefs.removeValueForKey(keyName); + default: + return false; + } + } + + return false; + } + + public clear(): boolean { + switch ($app) { + case "Quantumult X": + return $prefs.removeAllValues(); + default: + return false; + } + } + + #loadData(dataFile: string, fs: any, path: any): StorageData { + const curDirDataFilePath = path.resolve(dataFile); + const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); + if (fs.existsSync(curDirDataFilePath)) { + return JSON.parse(fs.readFileSync(curDirDataFilePath, "utf-8")) || {}; + } + if (fs.existsSync(rootDirDataFilePath)) { + return JSON.parse(fs.readFileSync(rootDirDataFilePath, "utf-8")) || {}; + } + return {}; + } + + #writeData(dataFile: string): void { + if ($app === "Node.js") { + const fs = require("node:fs"); + const path = require("node:path"); + const dataFilePath = path.resolve(dataFile); + fs.writeFileSync(dataFilePath, JSON.stringify(this.data), "utf-8"); + } + } +} + +// 导出初始化后的实例 +export const Storage = new StorageClass(); \ No newline at end of file diff --git a/src/polyfill/fetch.ts b/src/polyfill/fetch.ts new file mode 100644 index 0000000..30b8f46 --- /dev/null +++ b/src/polyfill/fetch.ts @@ -0,0 +1,218 @@ +import { $app } from "../lib/app"; +import {set} from "lodash"; +import { StatusTexts } from "./StatusTexts"; + +declare const $task: { + fetch: (options: FetchOptions) => Promise; +}; + +declare const $httpClient: { + [method: string]: (resource: any, callback: (error: any, response: any, body: any) => void) => void; +}; + +interface FetchOptions { + url?: string; + method?: string; + headers?: Record; + body?: any; + bodyBytes?: ArrayBuffer; + timeout: number; + policy?: string; + node?: string; + redirection?: boolean; + redirect?: string; + "auto-redirect"?: boolean; + "binary-mode"?: boolean; +} + +interface FetchResponse { + ok: boolean; + status: number; + statusCode: number; + statusText: string; + body: T; + bodyBytes?: ArrayBuffer; + headers: Record; +} + +// 定义需要二进制模式的 MIME 类型 +const binaryMimeTypes = [ + "application/protobuf", + "application/x-protobuf", + "application/vnd.google.protobuf", + "application/vnd.apple.flatbuffer", + "application/grpc", + "application/grpc+proto", + "application/octet-stream", +] + +export async function fetch(resource: string | FetchOptions, options: FetchOptions = { + timeout: 5 +}): Promise> { + let params = { ...options }; + // 初始化参数 + if (typeof resource === "string") { + params.url = resource; + } else if (typeof resource === "object") { + params = { ...params, ...resource }; + } else { + throw new TypeError(`${Function.name}: 参数类型错误, resource 必须为对象或字符串`); + } + + // 自动判断请求方法 + if (!params.method) { + params.method = "GET"; + if (params.body || params.bodyBytes) { + params.method = "POST" + }; + } + + // 移除请求头中的部分参数, 让其自动生成 + if (params.headers) { + params.headers.Host = undefined; + params.headers[":authority"] = undefined; + params.headers["Content-Length"] = undefined; + params.headers["content-length"] = undefined; + } + + // 定义请求方法(小写) + const method = params.method.toLocaleLowerCase(); + + // 转换请求超时时间参数 + if (params.timeout) { + params.timeout = Number.parseInt(params.timeout.toString(), 10); + // 转换为秒,大于500视为毫秒,小于等于500视为秒 + if (params.timeout > 500) { + params.timeout = Math.round(params.timeout / 1000); + } + } + + if ($app === 'Quantumult X') { + // 转换请求参数 + if (params.policy) { + set(params, "opts.policy", params.policy); + } + if (typeof params["auto-redirect"] === "boolean") { + set(params, "opts.redirection", params["auto-redirect"]); + } + // 转换请求体 + if (params.body instanceof ArrayBuffer) { + params.bodyBytes = params.body; + params.body = undefined; + } else if (ArrayBuffer.isView(params.body)) { + params.bodyBytes = params.body.buffer.slice(params.body.byteOffset, params.body.byteLength + params.body.byteOffset); + params.body = undefined; + } else if (params.body) { + params.bodyBytes = undefined; + } + // 发送请求 + return Promise.race([ + await $task.fetch(params).then(response => { + response.ok = /^2\d\d$/.test(response.statusCode); + response.status = response.statusCode; + response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; + if (binaryMimeTypes.includes((response.headers?.["Content-Type"] ?? response.headers?.["content-type"])?.split(";")?.[0])) { + response.body = response.bodyBytes; + } + response.bodyBytes = undefined; + return response; + }, reason => Promise.reject(reason.error)), + new Promise((_, reject) => { + setTimeout(() => { + reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); + }, params.timeout); + }), + ]) + } + + if ($app === "Node.js") { + const nodeFetch = globalThis.fetch ? globalThis.fetch : await import("node-fetch").then(module => module.default); + const fetchCookie = (globalThis as any).fetchCookie ? (globalThis as any).fetchCookie : await import("fetch-cookie").then(module => module.default); + const fetch = fetchCookie(nodeFetch); + // 转换请求参数 + params.timeout = (params.timeout ?? 5) * 1000; + params.redirect = params.redirection ? "follow" : "manual"; + const { url, ...options } = params; + // 发送请求 + return Promise.race([ + await fetch(url, options) + .then(async (response: any) => { + const bodyBytes = await response.arrayBuffer(); + let headers: any; + try { + headers = response.headers.raw(); + } catch { + headers = Array.from(response.headers.entries()).reduce((acc, item) => { + const [key, value] = item as [string, string]; + acc[key] = acc[key] ? [...acc[key], value] : [value]; + return acc; + }, {}); + } + return { + ok: response.ok ?? /^2\d\d$/.test(response.status), + status: response.status, + statusCode: response.status, + statusText: response.statusText, + body: new TextDecoder("utf-8").decode(bodyBytes), + bodyBytes: bodyBytes, + headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, key.toLowerCase() !== "set-cookie" ? (value as any).toString() : value])), + }; + }) + .catch((error: Error) => Promise.reject(error.message)), + new Promise((resolve, reject) => { + setTimeout(() => { + reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); + }, params.timeout); + }), + ]); + } + + if ($app === "Loon") { + params.timeout *= 1000; + } + if (params.policy) { + switch ($app) { + case "Loon": + params.node = params.policy; + break; + case "Stash": + set(params, "headers.X-Stash-Selected-Proxy", encodeURI(params.policy)); + break; + case "Shadowrocket": + set(params, "headers.X-Surge-Proxy", params.policy); + break; + default: + break; + } + } + if (typeof params.redirection === "boolean") { + params["auto-redirect"] = params.redirection + }; + // 转换请求体 + if (params.bodyBytes && !params.body) { + params.body = params.bodyBytes; + params.bodyBytes = undefined; + } + // 判断是否请求二进制响应体 + if (binaryMimeTypes.includes((params.headers?.Accept || params.headers?.accept)?.split(";")?.[0] ?? '')) { + params["binary-mode"] = true; + } + return new Promise((resolve, reject) => { + $httpClient[method](params, (error, response, body) => { + if (error) { + reject(error) + } else { + response.ok = /^2\d\d$/.test(response.status); + response.statusCode = response.status; + response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; + if (body) { + response.body = body; + if (params["binary-mode"]) { + response.bodyBytes = body; + } + } + resolve(response); + } + }); + }); +} diff --git a/src/polyfill/index.ts b/src/polyfill/index.ts new file mode 100644 index 0000000..3426e27 --- /dev/null +++ b/src/polyfill/index.ts @@ -0,0 +1,5 @@ +export * from "./Console"; +export * from "./fetch"; +export * from "./Lodash"; +export * from "./StatusTexts"; +export * from "./Storage"; diff --git a/tsconfig.json b/tsconfig.json index ca246d1..87506bf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,23 +1,17 @@ { - // Change this to match your project - "include": [ - "polyfill/URL.mts", - "polyfill/URLSearchParams.mts", - ], "compilerOptions": { - // Tells TypeScript to read JS files, as - // normally they are ignored as source files - "allowJs": true, - // Generate d.ts files - "declaration": true, - // This compiler run should - // only output d.ts files - "emitDeclarationOnly": false, - // go to js file when using IDE functions like - // "Go to Definition" in VSCode - "declarationMap": true, - "target": "ESNext", - "module": "ESNext", - "allowImportingTsExtensions": true, + "lib": ["ES2021"], + "module": "ESNext", + "target": "ES2021", + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "isolatedModules": true, + "resolveJsonModule": true, + "moduleResolution": "bundler", + "useDefineForClassFields": true, + "allowImportingTsExtensions": true }, -} + "include": ["src"] + } + \ No newline at end of file From 21c48daaecc59a62d6800b6bccc2048500d94b53 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 16:54:32 +0800 Subject: [PATCH 02/31] =?UTF-8?q?style:=20=E7=BB=9F=E4=B8=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=A3=8E=E6=A0=BC=EF=BC=8C=E8=B0=83=E6=95=B4=E5=BC=95?= =?UTF-8?q?=E5=8F=B7=E5=92=8C=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-package.yml | 1 - package.json | 19 +- rslib.config.ts | 10 +- src/env.d.ts | 6 +- src/getStorage.ts | 46 ++- src/index.ts | 22 +- src/lib/app.ts | 46 +-- src/lib/done.ts | 11 +- src/lib/environment.ts | 72 ++--- src/lib/index.ts | 10 +- src/lib/notification.ts | 174 ++++++----- src/lib/time.ts | 34 +-- src/lib/wait.ts | 2 +- src/polyfill/Console.ts | 97 +++--- src/polyfill/Lodash.ts | 14 +- src/polyfill/StatusTexts.ts | 120 ++++---- src/polyfill/Storage.ts | 323 ++++++++++---------- src/polyfill/fetch.ts | 408 ++++++++++++++------------ src/polyfill/index.ts | 10 +- test/test.js | 37 ++- tsconfig.json | 31 +- 21 files changed, 750 insertions(+), 743 deletions(-) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index ed1a7be..fda9f5e 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -28,7 +28,6 @@ jobs: node-version: 20 registry-url: ${{ matrix.registry }} - run: npm ci - - run: npm run build - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ matrix.registry == 'https://registry.npmjs.org' && secrets.NPM_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index e9ba20b..13ae7c1 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,7 @@ "type": "module", "author": "VirgilClyne ", "homepage": "https://NSNanoCat.github.io/util", - "keywords": [ - "loon", - "quantumult", - "surge", - "shadowrocket", - "stash", - "egern" - ], + "keywords": ["loon", "quantumult", "surge", "shadowrocket", "stash", "egern"], "license": "Apache-2.0", "bugs": "https://github.com/NSNanoCat/util/issues", "main": "./dist/index.cjs", @@ -40,15 +33,17 @@ } }, "scripts": { - "build": "rslib build" + "build": "rslib build", + "check": "biome check --write", + "dev": "rslib build --watch", + "format": "biome format --write", + "prepublishOnly": "npm run build" }, "repository": { "type": "git", "url": "https://github.com/NSNanoCat/util.git" }, - "files": [ - "dist" - ], + "files": ["dist"], "dependencies": { "lodash": "^4.17.21" }, diff --git a/rslib.config.ts b/rslib.config.ts index cf60c55..3242a28 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -2,18 +2,18 @@ import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ - { format: 'esm', syntax: 'es2021', bundle: false, dts: true, }, + { format: 'esm', syntax: 'es2021', bundle: false, dts: true }, { format: 'cjs', syntax: 'es2021', bundle: false }, ], source: { entry: { - index: './src/**' + index: './src/**', }, transformImport: [ { libraryName: 'lodash', customName: 'lodash/{{ member }}', }, - ] - } -}); \ No newline at end of file + ], + }, +}); diff --git a/src/env.d.ts b/src/env.d.ts index e87d9a5..5b271d6 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,5 +1,5 @@ interface Environment { - "loon-version"?: string; + 'loon-version'?: string; 'surge-version'?: string; 'stash-version'?: string; } @@ -7,5 +7,5 @@ interface Environment { // biome-ignore lint/suspicious/useNamespaceKeyword: This is a global declaration file declare module globalThis { // biome-ignore lint/style/noVar: This is a global declaration file - var $environment: Environment -} \ No newline at end of file + var $environment: Environment; +} diff --git a/src/getStorage.ts b/src/getStorage.ts index 0aac517..415c668 100644 --- a/src/getStorage.ts +++ b/src/getStorage.ts @@ -1,5 +1,5 @@ -import { set } from "lodash"; -import { Storage } from "./polyfill/Storage"; +import { set } from 'lodash'; +import { Storage } from './polyfill/Storage'; type Database = Record; @@ -13,11 +13,13 @@ interface StoreType< Caches: Caches; } -declare const $argument: string | object +declare const $argument: string | object; -export function getStorage = Record, +export function getStorage< + Settings extends Record = Record, Configs extends Record = Record, - Caches extends Record = Record,>(key: string, names: string | string[], database: Database): StoreType { + Caches extends Record = Record, +>(key: string, names: string | string[], database: Database): StoreType { const nameList = Array.isArray(names) ? names : [names]; const Store = { @@ -31,12 +33,12 @@ export function getStorage = Record item.split("=", 2).map((i) => i.replace(/\"/g, ""))) + $argument.split('&').map((item) => item.split('=', 2).map((i) => i.replace(/\"/g, ''))), ); Object.keys(parsedArgument).forEach((key) => set(Store.Settings, key, parsedArgument[key])); - } else if (typeof $argument === "object") { + } else if (typeof $argument === 'object') { Object.keys($argument).forEach((key) => set(Store.Settings, key, $argument[key as keyof typeof $argument])); } @@ -46,19 +48,19 @@ export function getStorage = Record { + nameList.forEach((name) => { const boxSettings = BoxJs?.[name]?.Settings; const boxCaches = BoxJs?.[name]?.Caches; - if (typeof boxSettings === "string") { - BoxJs[name].Settings = JSON.parse(boxSettings || "{}"); + if (typeof boxSettings === 'string') { + BoxJs[name].Settings = JSON.parse(boxSettings || '{}'); } if (boxSettings) { Store.Settings = { ...Store.Settings, ...BoxJs[name].Settings }; } - if (typeof boxCaches === "string") { - BoxJs[name].Caches = JSON.parse(boxCaches || "{}"); + if (typeof boxCaches === 'string') { + BoxJs[name].Caches = JSON.parse(boxCaches || '{}'); } if (boxCaches) { Store.Caches = { ...Store.Caches, ...BoxJs[name].Caches }; @@ -70,11 +72,11 @@ export function getStorage = Record { //Console.debug("☑️ traverseObject", `${key}: ${typeof value}`, `${key}: ${JSON.stringify(value)}`); let transformedValue = value; - if (transformedValue === "true" || transformedValue === "false") + if (transformedValue === 'true' || transformedValue === 'false') transformedValue = JSON.parse(transformedValue); // 字符串转Boolean - else if (typeof transformedValue === "string") { - if (transformedValue.includes(",")) - transformedValue = transformedValue.split(",").map(item => string2number(item)); // 字符串转数组转数字 + else if (typeof transformedValue === 'string') { + if (transformedValue.includes(',')) + transformedValue = transformedValue.split(',').map((item) => string2number(item)); // 字符串转数组转数字 else transformedValue = string2number(transformedValue); // 字符串转数字 } return transformedValue; @@ -83,16 +85,12 @@ export function getStorage = Record( - obj: Record, - callback: (key: string, value: any) => any -): Record { +function traverseObject(obj: Record, callback: (key: string, value: any) => any): Record { Object.entries(obj).forEach(([key, value]) => { - if (value && typeof value === "object") { + if (value && typeof value === 'object') { obj[key] = traverseObject(value, callback); } else { obj[key] = callback(key, value); @@ -106,4 +104,4 @@ function traverseObject( */ function string2number(value: string): number | string { return /^\d+$/.test(value) ? Number(value) : value; -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index 968edd0..268b834 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ -export * from "./lib/app"; -export * from "./lib/done"; -export * from "./lib/notification"; -export * from "./lib/time"; -export * from "./lib/wait"; -export * from "./polyfill/Console"; -export * from "./polyfill/fetch"; -export * from "./polyfill/Lodash"; -export * from "./polyfill/StatusTexts"; -export * from "./polyfill/Storage"; -export * from "./getStorage"; +export * from './lib/app'; +export * from './lib/done'; +export * from './lib/notification'; +export * from './lib/time'; +export * from './lib/wait'; +export * from './polyfill/Console'; +export * from './polyfill/fetch'; +export * from './polyfill/Lodash'; +export * from './polyfill/StatusTexts'; +export * from './polyfill/Storage'; +export * from './getStorage'; diff --git a/src/lib/app.ts b/src/lib/app.ts index 15c0b19..407268a 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -2,27 +2,27 @@ * Current app name */ export const $app = (() => { - if ("$task" in globalThis) { - return "Quantumult X"; - } - if ("$loon" in globalThis) { - return "Loon"; - } - if ("$rocket" in globalThis) { - return "Shadowrocket"; - } - if ("Egern" in globalThis) { - return "Egern"; - } - if ("$environment" in globalThis) { - if (globalThis.$environment["surge-version"]) { - return "Surge"; - } - if (globalThis.$environment["stash-version"]) { - return "Stash"; - } - } - if (typeof module !== "undefined") { - return "Node.js"; - } + if ('$task' in globalThis) { + return 'Quantumult X'; + } + if ('$loon' in globalThis) { + return 'Loon'; + } + if ('$rocket' in globalThis) { + return 'Shadowrocket'; + } + if ('Egern' in globalThis) { + return 'Egern'; + } + if ('$environment' in globalThis) { + if (globalThis.$environment['surge-version']) { + return 'Surge'; + } + if (globalThis.$environment['stash-version']) { + return 'Stash'; + } + } + if (typeof module !== 'undefined') { + return 'Node.js'; + } })(); diff --git a/src/lib/done.ts b/src/lib/done.ts index 796bdc5..dee3e1c 100644 --- a/src/lib/done.ts +++ b/src/lib/done.ts @@ -1,7 +1,7 @@ -import { $app } from './app'; +import { pick, set } from 'lodash'; import { Console } from '../polyfill/Console'; import { StatusTexts } from '../polyfill/StatusTexts'; -import { pick, set } from 'lodash'; +import { $app } from './app'; interface DoneObject { status?: number | string; @@ -50,9 +50,8 @@ const handleDoneFactory = (startTime?: number) => { return (result: DoneObject) => { Console.log('🚩 执行结束!', startTime ? `🕛 ${((Date.now() - startTime) / 1000).toFixed(3)} 秒` : undefined); $done(result); - } -} - + }; +}; /** * Complete the script execution @@ -109,7 +108,7 @@ export function done(object: DoneObject = {}): void { } case 'Node.js': default: - Console.log("🚩 执行结束!"); + Console.log('🚩 执行结束!'); process.exit(1); } } diff --git a/src/lib/environment.ts b/src/lib/environment.ts index aa45e6c..cc01b69 100644 --- a/src/lib/environment.ts +++ b/src/lib/environment.ts @@ -1,47 +1,47 @@ -import { $app } from "./app"; +import { $app } from './app'; interface Environment extends globalThis.Environment { - app?: string; - device?: string; - ios?: string; - [key: string]: string | undefined; + app?: string; + device?: string; + ios?: string; + [key: string]: string | undefined; } declare const $loon: string; declare const $environment: Environment; export function environment(): Environment { - switch ($app) { - case "Surge": - $environment.app = "Surge"; - return $environment; - case "Stash": - $environment.app = "Stash"; - return $environment; - case "Egern": - $environment.app = "Egern"; - return $environment; - case "Loon": { - const environment = $loon.split(" "); - return { - device: environment[0], - ios: environment[1], - "loon-version": environment[2], - app: "Loon", - }; - } - case "Quantumult X": - return { - app: "Quantumult X", - }; - case "Node.js": - return { - ...process.env, - app: "Node.js", - }; - default: - return {}; - } + switch ($app) { + case 'Surge': + $environment.app = 'Surge'; + return $environment; + case 'Stash': + $environment.app = 'Stash'; + return $environment; + case 'Egern': + $environment.app = 'Egern'; + return $environment; + case 'Loon': { + const environment = $loon.split(' '); + return { + device: environment[0], + ios: environment[1], + 'loon-version': environment[2], + app: 'Loon', + }; + } + case 'Quantumult X': + return { + app: 'Quantumult X', + }; + case 'Node.js': + return { + ...process.env, + app: 'Node.js', + }; + default: + return {}; + } } // export const $environment = environment(); diff --git a/src/lib/index.ts b/src/lib/index.ts index ebb0110..9ad1827 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,5 +1,5 @@ -export * from "./app"; -export * from "./done"; -export * from "./notification"; -export * from "./time"; -export * from "./wait"; +export * from './app'; +export * from './done'; +export * from './notification'; +export * from './time'; +export * from './wait'; diff --git a/src/lib/notification.ts b/src/lib/notification.ts index 00272b0..a14ba6b 100644 --- a/src/lib/notification.ts +++ b/src/lib/notification.ts @@ -1,18 +1,18 @@ -import { $app } from "./app.js"; -import { Console } from "../polyfill/Console.js"; +import { Console } from '../polyfill/Console.js'; +import { $app } from './app.js'; interface NotificationContent { open?: string; - "open-url"?: string; + 'open-url'?: string; url?: string; openUrl?: string; copy?: string; - "update-pasteboard"?: string; + 'update-pasteboard'?: string; updatePasteboard?: string; media?: string; - "media-url"?: string; + 'media-url'?: string; mediaUrl?: string; - "auto-dismiss"?: boolean; + 'auto-dismiss'?: boolean; sound?: string; mime?: string; } @@ -27,23 +27,23 @@ declare const $notification: { */ export function notification( title = `ℹ️ ${$app} 通知`, - subtitle = "", - body = "", - content: string | number | boolean | NotificationContent = {} + subtitle = '', + body = '', + content: string | number | boolean | NotificationContent = {}, ): void { const mutableContent = getMutableContent(content); switch ($app) { - case "Quantumult X": + case 'Quantumult X': $notify(title, subtitle, body, mutableContent); break; - case "Node.js": + case 'Node.js': break; default: $notification.post(title, subtitle, body, mutableContent); break; } - Console.group("📣 系统通知"); + Console.group('📣 系统通知'); Console.log(title, subtitle, body, JSON.stringify(mutableContent, null, 2)); Console.groupEnd(); } @@ -52,21 +52,21 @@ function getMutableContent(content: string | number | boolean | NotificationCont const mutableContent: Record = {}; switch (typeof content) { - case "string": - case "number": - case "boolean": - assignSimpleContent(mutableContent, content); - break; - - case "object": - if (content) { - assignObjectContent(mutableContent, content); - } - break; - - default: - Console.error(`不支持的通知参数类型: ${typeof content}`); - break; + case 'string': + case 'number': + case 'boolean': + assignSimpleContent(mutableContent, content); + break; + + case 'object': + if (content) { + assignObjectContent(mutableContent, content); + } + break; + + default: + Console.error(`不支持的通知参数类型: ${typeof content}`); + break; } return mutableContent; @@ -74,79 +74,75 @@ function getMutableContent(content: string | number | boolean | NotificationCont function assignSimpleContent(mutableContent: Record, content: string | number | boolean): void { switch ($app) { - case "Quantumult X": - mutableContent["open-url"] = content; - break; - case "Loon": - case "Shadowrocket": - mutableContent.openUrl = content; - break; - default: - mutableContent.url = content; - break; + case 'Quantumult X': + mutableContent['open-url'] = content; + break; + case 'Loon': + case 'Shadowrocket': + mutableContent.openUrl = content; + break; + default: + mutableContent.url = content; + break; } } function assignObjectContent(mutableContent: Record, content: NotificationContent): void { - const openUrl = content.open || content["open-url"] || content.url || content.openUrl; - const copyUrl = content.copy || content["update-pasteboard"] || content.updatePasteboard; - const mediaUrl = content.media || content["media-url"] || content.mediaUrl; + const openUrl = content.open || content['open-url'] || content.url || content.openUrl; + const copyUrl = content.copy || content['update-pasteboard'] || content.updatePasteboard; + const mediaUrl = content.media || content['media-url'] || content.mediaUrl; switch ($app) { - case "Quantumult X": - if (openUrl) mutableContent["open-url"] = openUrl; - if (mediaUrl?.startsWith("http")) mutableContent["media-url"] = mediaUrl; - if (copyUrl) mutableContent["update-pasteboard"] = copyUrl; - break; - - case "Loon": - if (openUrl) mutableContent.openUrl = openUrl; - if (mediaUrl?.startsWith("http")) mutableContent.mediaUrl = mediaUrl; - break; - - default: - if (openUrl) { - mutableContent.action = "open-url"; - mutableContent.url = openUrl; - } - if (copyUrl) { - mutableContent.action = "clipboard"; - mutableContent.text = copyUrl; - } - if (mediaUrl) { - handleMediaContent(mutableContent, mediaUrl, content.mime); - } - if (content["auto-dismiss"]) mutableContent["auto-dismiss"] = content["auto-dismiss"]; - if (content.sound) mutableContent.sound = content.sound; - break; + case 'Quantumult X': + if (openUrl) mutableContent['open-url'] = openUrl; + if (mediaUrl?.startsWith('http')) mutableContent['media-url'] = mediaUrl; + if (copyUrl) mutableContent['update-pasteboard'] = copyUrl; + break; + + case 'Loon': + if (openUrl) mutableContent.openUrl = openUrl; + if (mediaUrl?.startsWith('http')) mutableContent.mediaUrl = mediaUrl; + break; + + default: + if (openUrl) { + mutableContent.action = 'open-url'; + mutableContent.url = openUrl; + } + if (copyUrl) { + mutableContent.action = 'clipboard'; + mutableContent.text = copyUrl; + } + if (mediaUrl) { + handleMediaContent(mutableContent, mediaUrl, content.mime); + } + if (content['auto-dismiss']) mutableContent['auto-dismiss'] = content['auto-dismiss']; + if (content.sound) mutableContent.sound = content.sound; + break; } } -function handleMediaContent( - mutableContent: Record, - mediaUrl: string, - mime?: string -): void { - if (mediaUrl.startsWith("http")) { - mutableContent["media-url"] = mediaUrl; - } else if (mediaUrl.startsWith("data:")) { - const base64RegExp = /^data:(?\w+\/\w+);base64,(?.+)/; - const match = mediaUrl.match(base64RegExp); - if (match?.groups) { - mutableContent["media-base64"] = match.groups.Base64; - mutableContent["media-base64-mime"] = mime || match.groups.MIME; - } +function handleMediaContent(mutableContent: Record, mediaUrl: string, mime?: string): void { + if (mediaUrl.startsWith('http')) { + mutableContent['media-url'] = mediaUrl; + } else if (mediaUrl.startsWith('data:')) { + const base64RegExp = /^data:(?\w+\/\w+);base64,(?.+)/; + const match = mediaUrl.match(base64RegExp); + if (match?.groups) { + mutableContent['media-base64'] = match.groups.Base64; + mutableContent['media-base64-mime'] = mime || match.groups.MIME; + } } else { - mutableContent["media-base64"] = mediaUrl; - mutableContent["media-base64-mime"] = detectMimeType(mediaUrl); + mutableContent['media-base64'] = mediaUrl; + mutableContent['media-base64-mime'] = detectMimeType(mediaUrl); } } function detectMimeType(base64: string): string { - if (base64.startsWith("JVBERi0")) return "application/pdf"; - if (base64.startsWith("R0lGODdh") || base64.startsWith("R0lGODlh")) return "image/gif"; - if (base64.startsWith("iVBORw0KGgo")) return "image/png"; - if (base64.startsWith("/9j/")) return "image/jpeg"; - if (base64.startsWith("Qk02U")) return "image/bmp"; - return "application/octet-stream"; -} \ No newline at end of file + if (base64.startsWith('JVBERi0')) return 'application/pdf'; + if (base64.startsWith('R0lGODdh') || base64.startsWith('R0lGODlh')) return 'image/gif'; + if (base64.startsWith('iVBORw0KGgo')) return 'image/png'; + if (base64.startsWith('/9j/')) return 'image/jpeg'; + if (base64.startsWith('Qk02U')) return 'image/bmp'; + return 'application/octet-stream'; +} diff --git a/src/lib/time.ts b/src/lib/time.ts index 354dc04..0729605 100644 --- a/src/lib/time.ts +++ b/src/lib/time.ts @@ -11,21 +11,21 @@ * */ export function time(format: string, ts: number): string { - const date = ts ? new Date(ts) : new Date(); - const Time = { - YY: date.getFullYear().toString().substring(3), - yyyy: date.getFullYear().toString(), - MM: (date.getMonth() + 1).toString().padStart(2, "0"), - dd: date.getDate().toString().padStart(2, "0"), - HH: date.getHours().toString().padStart(2, "0"), - mm: date.getMinutes().toString().padStart(2, "0"), - sss: date.getMilliseconds().toString().padStart(3, "0"), - ss: date.getSeconds().toString().padStart(2, "0"), - S: `${Math.floor(date.getMonth() / 3) + 1}`, - }; - let result = format; - for (const [key, value] of Object.entries(Time)) { - result = result.replace(key, value); - } - return result; + const date = ts ? new Date(ts) : new Date(); + const Time = { + YY: date.getFullYear().toString().substring(3), + yyyy: date.getFullYear().toString(), + MM: (date.getMonth() + 1).toString().padStart(2, '0'), + dd: date.getDate().toString().padStart(2, '0'), + HH: date.getHours().toString().padStart(2, '0'), + mm: date.getMinutes().toString().padStart(2, '0'), + sss: date.getMilliseconds().toString().padStart(3, '0'), + ss: date.getSeconds().toString().padStart(2, '0'), + S: `${Math.floor(date.getMonth() / 3) + 1}`, + }; + let result = format; + for (const [key, value] of Object.entries(Time)) { + result = result.replace(key, value); + } + return result; } diff --git a/src/lib/wait.ts b/src/lib/wait.ts index 1d28c70..ab7f13c 100644 --- a/src/lib/wait.ts +++ b/src/lib/wait.ts @@ -2,5 +2,5 @@ * wait */ export function wait(delay = 1000) { - return new Promise(resolve => setTimeout(resolve, delay)); + return new Promise((resolve) => setTimeout(resolve, delay)); } diff --git a/src/polyfill/Console.ts b/src/polyfill/Console.ts index 7726c64..e93856b 100644 --- a/src/polyfill/Console.ts +++ b/src/polyfill/Console.ts @@ -1,13 +1,13 @@ -import { $app } from "../lib/app"; +import { $app } from '../lib/app'; class ConsoleFactory { #counts = new Map([]); #groups: string[] = []; #times = new Map([]); - clear = () => { }; + clear = () => {}; - count = (label = "default") => { + count = (label = 'default') => { if (this.#counts.has(label)) { this.#counts.set(label, this.#counts.get(label) ?? 0 + 1); } else { @@ -16,7 +16,7 @@ class ConsoleFactory { this.log(`${label}: ${this.#counts.get(label)}`); }; - countReset = (label = "default") => { + countReset = (label = 'default') => { switch (this.#counts.has(label)) { case true: this.#counts.set(label, 0); @@ -36,19 +36,21 @@ class ConsoleFactory { error(...msg: any[]) { if (this.#level < 1) return; switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - case "Quantumult X": - case "Node.js": - this.log(...msg.map((m) => { - if (m instanceof Error) { - return `❌ ${m.stack}` - } - return `❌ ${m}` - })); + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + case 'Quantumult X': + case 'Node.js': + this.log( + ...msg.map((m) => { + if (m instanceof Error) { + return `❌ ${m.stack}`; + } + return `❌ ${m}`; + }), + ); break; default: this.log(...msg.map((m) => `❌ ${m}`)); @@ -72,58 +74,58 @@ class ConsoleFactory { get logLevel() { switch (this.#level) { case 0: - return "OFF"; + return 'OFF'; case 1: - return "ERROR"; + return 'ERROR'; case 2: - return "WARN"; + return 'WARN'; case 4: - return "DEBUG"; + return 'DEBUG'; case 5: - return "ALL"; + return 'ALL'; case 3: default: - return "INFO"; + return 'INFO'; } } set logLevel(_level: string | number) { let level = _level; switch (typeof level) { - case "string": + case 'string': level = level.toLowerCase(); break; - case "number": + case 'number': break; - case "undefined": + case 'undefined': default: - level = "warn"; + level = 'warn'; break; } switch (level) { case 0: - case "off": + case 'off': this.#level = 0; break; case 1: - case "error": + case 'error': this.#level = 1; break; case 3: - case "info": + case 'info': this.#level = 3; break; case 4: - case "debug": + case 'debug': this.#level = 4; break; case 5: - case "all": + case 'all': this.#level = 5; break; case 2: - case "warn": - case "warning": + case 'warn': + case 'warning': default: this.#level = 2; break; @@ -132,20 +134,20 @@ class ConsoleFactory { log = (...args: any[]) => { if (this.#level === 0) return; - let msg = args + let msg = args; msg = msg.map((item) => { let log = item; switch (typeof log) { - case "object": + case 'object': log = JSON.stringify(log); break; - case "bigint": - case "number": - case "boolean": - case "string": + case 'bigint': + case 'number': + case 'boolean': + case 'string': log = log.toString(); break; - case "undefined": + case 'undefined': default: break; } @@ -155,15 +157,15 @@ class ConsoleFactory { msg = msg.map((log) => ` ${log}`); msg.unshift(`▼ ${group}:`); }); - msg = ["", ...msg]; - console.log(msg.join("\n")); + msg = ['', ...msg]; + console.log(msg.join('\n')); }; - time = (label = "default") => this.#times.set(label, Date.now()); + time = (label = 'default') => this.#times.set(label, Date.now()); - timeEnd = (label = "default") => this.#times.delete(label); + timeEnd = (label = 'default') => this.#times.delete(label); - timeLog = (label = "default") => { + timeLog = (label = 'default') => { const time = this.#times.get(label); if (time) { this.log(`${label}: ${Date.now() - time}ms`); @@ -182,5 +184,4 @@ class ConsoleFactory { } } - -export const Console = new ConsoleFactory(); \ No newline at end of file +export const Console = new ConsoleFactory(); diff --git a/src/polyfill/Lodash.ts b/src/polyfill/Lodash.ts index 7f13d28..0a6b9eb 100644 --- a/src/polyfill/Lodash.ts +++ b/src/polyfill/Lodash.ts @@ -1,14 +1,4 @@ -import { - escape as lodashEscape, - get, - omit, - pick, - set, - toPath, - unescape as lodashUnescape, - unset, -} from 'lodash' - +import { get, escape as lodashEscape, unescape as lodashUnescape, omit, pick, set, toPath, unset } from 'lodash'; export const Lodash = { escape: lodashEscape, @@ -19,4 +9,4 @@ export const Lodash = { toPath, unescape: lodashUnescape, unset, -} +}; diff --git a/src/polyfill/StatusTexts.ts b/src/polyfill/StatusTexts.ts index 26a3d71..ad4f864 100644 --- a/src/polyfill/StatusTexts.ts +++ b/src/polyfill/StatusTexts.ts @@ -1,62 +1,62 @@ export const StatusTexts = { - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 103: "Early Hints", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi-Status", - 208: "Already Reported", - 226: "IM Used", - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 304: "Not Modified", - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Content Too Large", - 414: "URI Too Long", - 415: "Unsupported Media Type", - 416: "Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", - 421: "Misdirected Request", - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 425: "Too Early", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required", + 100: 'Continue', + 101: 'Switching Protocols', + 102: 'Processing', + 103: 'Early Hints', + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + 207: 'Multi-Status', + 208: 'Already Reported', + 226: 'IM Used', + 300: 'Multiple Choices', + 301: 'Moved Permanently', + 302: 'Found', + 304: 'Not Modified', + 307: 'Temporary Redirect', + 308: 'Permanent Redirect', + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Content Too Large', + 414: 'URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Range Not Satisfiable', + 417: 'Expectation Failed', + 418: "I'm a teapot", + 421: 'Misdirected Request', + 422: 'Unprocessable Entity', + 423: 'Locked', + 424: 'Failed Dependency', + 425: 'Too Early', + 426: 'Upgrade Required', + 428: 'Precondition Required', + 429: 'Too Many Requests', + 431: 'Request Header Fields Too Large', + 451: 'Unavailable For Legal Reasons', + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 508: 'Loop Detected', + 510: 'Not Extended', + 511: 'Network Authentication Required', }; diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts index afb602f..715a1f7 100644 --- a/src/polyfill/Storage.ts +++ b/src/polyfill/Storage.ts @@ -1,174 +1,173 @@ -import { get, set, unset } from "lodash"; -import { $app } from "../lib/app"; - +import { get, set, unset } from 'lodash'; +import { $app } from '../lib/app'; declare const $persistentStore: { - read: (key: string) => string | null; - write: (value: string, key: string) => boolean; -} + read: (key: string) => string | null; + write: (value: string, key: string) => boolean; +}; declare const $prefs: { - valueForKey: (key: string) => string | null; - setValueForKey: (value: string, key: string) => boolean; - removeValueForKey: (key: string) => boolean; - removeAllValues: () => boolean; -} + valueForKey: (key: string) => string | null; + setValueForKey: (value: string, key: string) => boolean; + removeValueForKey: (key: string) => boolean; + removeAllValues: () => boolean; +}; interface StorageData { - [key: string]: any; + [key: string]: any; } export class StorageClass { - private data: StorageData | null = null; - private readonly dataFile: string = "box.dat"; - private readonly nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; - - constructor() { - if ($app === "Node.js") { - const fs = require("node:fs"); - const path = require("node:path"); - this.data = this.#loadData(this.dataFile, fs, path); - } - } - - public getItem(keyName: string, defaultValue = null as T): T { - let keyValue = defaultValue; - - if (keyName.startsWith("@")) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key, {}); - if (typeof value !== "object") { - value = {}; - } - keyValue = get(value, path); - try { - keyValue = JSON.parse(keyValue as string); - } catch { - // Ignore parse error - } - } - } else { - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - keyValue = $persistentStore.read(keyName) as T; - break; - case "Quantumult X": - keyValue = $prefs.valueForKey(keyName) as T; - break; - case "Node.js": - this.data = this.data || {}; - keyValue = this.data[keyName]; - break; - default: - keyValue = null as T; - break; - } - - try { - keyValue = JSON.parse(keyValue as string); - } catch { - // Ignore parse error - } - } - - return keyValue ?? defaultValue; - } - - public setItem(keyName: string, value: any): boolean { - let keyValue = value; - if (typeof keyValue === "object") { - keyValue = JSON.stringify(keyValue); - } else { - keyValue = String(keyValue); - } - - if (keyName.startsWith("@")) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key, {}); - if (typeof value !== "object") value = {}; - set(value, path, keyValue); - return this.setItem(keyName, value); - } - } else { - switch ($app) { - case "Surge": - case "Loon": - case "Stash": - case "Egern": - case "Shadowrocket": - return $persistentStore.write(keyValue, keyName); - case "Quantumult X": - return $prefs.setValueForKey(keyValue, keyName); - case "Node.js": - this.data = this.data || {}; - this.data[keyName] = keyValue; - this.#writeData(this.dataFile); - return true; - default: - return false; - } - } - - return false; - } - - public removeItem(keyName: string): boolean { - if (keyName.startsWith("@")) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key); - if (typeof value !== "object") value = {}; - unset(value, path); - return this.setItem(key, value); - } - } else { - switch ($app) { - case "Quantumult X": - return $prefs.removeValueForKey(keyName); - default: - return false; - } - } - - return false; - } - - public clear(): boolean { - switch ($app) { - case "Quantumult X": - return $prefs.removeAllValues(); - default: - return false; - } - } - - #loadData(dataFile: string, fs: any, path: any): StorageData { - const curDirDataFilePath = path.resolve(dataFile); - const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); - if (fs.existsSync(curDirDataFilePath)) { - return JSON.parse(fs.readFileSync(curDirDataFilePath, "utf-8")) || {}; - } - if (fs.existsSync(rootDirDataFilePath)) { - return JSON.parse(fs.readFileSync(rootDirDataFilePath, "utf-8")) || {}; - } - return {}; - } - - #writeData(dataFile: string): void { - if ($app === "Node.js") { - const fs = require("node:fs"); - const path = require("node:path"); - const dataFilePath = path.resolve(dataFile); - fs.writeFileSync(dataFilePath, JSON.stringify(this.data), "utf-8"); - } - } + private data: StorageData | null = null; + private readonly dataFile: string = 'box.dat'; + private readonly nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; + + constructor() { + if ($app === 'Node.js') { + const fs = require('node:fs'); + const path = require('node:path'); + this.data = this.#loadData(this.dataFile, fs, path); + } + } + + public getItem(keyName: string, defaultValue = null as T): T { + let keyValue = defaultValue; + + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== 'object') { + value = {}; + } + keyValue = get(value, path); + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + } else { + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + keyValue = $persistentStore.read(keyName) as T; + break; + case 'Quantumult X': + keyValue = $prefs.valueForKey(keyName) as T; + break; + case 'Node.js': + this.data = this.data || {}; + keyValue = this.data[keyName]; + break; + default: + keyValue = null as T; + break; + } + + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + + return keyValue ?? defaultValue; + } + + public setItem(keyName: string, value: any): boolean { + let keyValue = value; + if (typeof keyValue === 'object') { + keyValue = JSON.stringify(keyValue); + } else { + keyValue = String(keyValue); + } + + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== 'object') value = {}; + set(value, path, keyValue); + return this.setItem(keyName, value); + } + } else { + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + return $persistentStore.write(keyValue, keyName); + case 'Quantumult X': + return $prefs.setValueForKey(keyValue, keyName); + case 'Node.js': + this.data = this.data || {}; + this.data[keyName] = keyValue; + this.#writeData(this.dataFile); + return true; + default: + return false; + } + } + + return false; + } + + public removeItem(keyName: string): boolean { + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key); + if (typeof value !== 'object') value = {}; + unset(value, path); + return this.setItem(key, value); + } + } else { + switch ($app) { + case 'Quantumult X': + return $prefs.removeValueForKey(keyName); + default: + return false; + } + } + + return false; + } + + public clear(): boolean { + switch ($app) { + case 'Quantumult X': + return $prefs.removeAllValues(); + default: + return false; + } + } + + #loadData(dataFile: string, fs: any, path: any): StorageData { + const curDirDataFilePath = path.resolve(dataFile); + const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); + if (fs.existsSync(curDirDataFilePath)) { + return JSON.parse(fs.readFileSync(curDirDataFilePath, 'utf-8')) || {}; + } + if (fs.existsSync(rootDirDataFilePath)) { + return JSON.parse(fs.readFileSync(rootDirDataFilePath, 'utf-8')) || {}; + } + return {}; + } + + #writeData(dataFile: string): void { + if ($app === 'Node.js') { + const fs = require('node:fs'); + const path = require('node:path'); + const dataFilePath = path.resolve(dataFile); + fs.writeFileSync(dataFilePath, JSON.stringify(this.data), 'utf-8'); + } + } } // 导出初始化后的实例 -export const Storage = new StorageClass(); \ No newline at end of file +export const Storage = new StorageClass(); diff --git a/src/polyfill/fetch.ts b/src/polyfill/fetch.ts index 30b8f46..bcefe9a 100644 --- a/src/polyfill/fetch.ts +++ b/src/polyfill/fetch.ts @@ -1,218 +1,238 @@ -import { $app } from "../lib/app"; -import {set} from "lodash"; -import { StatusTexts } from "./StatusTexts"; +import { set } from 'lodash'; +import { $app } from '../lib/app'; +import { StatusTexts } from './StatusTexts'; declare const $task: { - fetch: (options: FetchOptions) => Promise; + fetch: (options: FetchOptions) => Promise; }; declare const $httpClient: { - [method: string]: (resource: any, callback: (error: any, response: any, body: any) => void) => void; + [method: string]: (resource: any, callback: (error: any, response: any, body: any) => void) => void; }; interface FetchOptions { - url?: string; - method?: string; - headers?: Record; - body?: any; - bodyBytes?: ArrayBuffer; - timeout: number; - policy?: string; - node?: string; - redirection?: boolean; - redirect?: string; - "auto-redirect"?: boolean; - "binary-mode"?: boolean; + url?: string; + method?: string; + headers?: Record; + body?: any; + bodyBytes?: ArrayBuffer; + timeout: number; + policy?: string; + node?: string; + redirection?: boolean; + redirect?: string; + 'auto-redirect'?: boolean; + 'binary-mode'?: boolean; } interface FetchResponse { - ok: boolean; - status: number; - statusCode: number; - statusText: string; - body: T; - bodyBytes?: ArrayBuffer; - headers: Record; + ok: boolean; + status: number; + statusCode: number; + statusText: string; + body: T; + bodyBytes?: ArrayBuffer; + headers: Record; } // 定义需要二进制模式的 MIME 类型 const binaryMimeTypes = [ - "application/protobuf", - "application/x-protobuf", - "application/vnd.google.protobuf", - "application/vnd.apple.flatbuffer", - "application/grpc", - "application/grpc+proto", - "application/octet-stream", -] + 'application/protobuf', + 'application/x-protobuf', + 'application/vnd.google.protobuf', + 'application/vnd.apple.flatbuffer', + 'application/grpc', + 'application/grpc+proto', + 'application/octet-stream', +]; -export async function fetch(resource: string | FetchOptions, options: FetchOptions = { - timeout: 5 -}): Promise> { - let params = { ...options }; - // 初始化参数 - if (typeof resource === "string") { - params.url = resource; - } else if (typeof resource === "object") { - params = { ...params, ...resource }; - } else { - throw new TypeError(`${Function.name}: 参数类型错误, resource 必须为对象或字符串`); - } +export async function fetch( + resource: string | FetchOptions, + options: FetchOptions = { + timeout: 5, + }, +): Promise> { + let params = { ...options }; + // 初始化参数 + if (typeof resource === 'string') { + params.url = resource; + } else if (typeof resource === 'object') { + params = { ...params, ...resource }; + } else { + throw new TypeError(`${Function.name}: 参数类型错误, resource 必须为对象或字符串`); + } - // 自动判断请求方法 - if (!params.method) { - params.method = "GET"; - if (params.body || params.bodyBytes) { - params.method = "POST" - }; - } + // 自动判断请求方法 + if (!params.method) { + params.method = 'GET'; + if (params.body || params.bodyBytes) { + params.method = 'POST'; + } + } - // 移除请求头中的部分参数, 让其自动生成 - if (params.headers) { - params.headers.Host = undefined; - params.headers[":authority"] = undefined; - params.headers["Content-Length"] = undefined; - params.headers["content-length"] = undefined; - } + // 移除请求头中的部分参数, 让其自动生成 + if (params.headers) { + params.headers.Host = undefined; + params.headers[':authority'] = undefined; + params.headers['Content-Length'] = undefined; + params.headers['content-length'] = undefined; + } - // 定义请求方法(小写) - const method = params.method.toLocaleLowerCase(); + // 定义请求方法(小写) + const method = params.method.toLocaleLowerCase(); - // 转换请求超时时间参数 - if (params.timeout) { - params.timeout = Number.parseInt(params.timeout.toString(), 10); - // 转换为秒,大于500视为毫秒,小于等于500视为秒 - if (params.timeout > 500) { - params.timeout = Math.round(params.timeout / 1000); - } - } + // 转换请求超时时间参数 + if (params.timeout) { + params.timeout = Number.parseInt(params.timeout.toString(), 10); + // 转换为秒,大于500视为毫秒,小于等于500视为秒 + if (params.timeout > 500) { + params.timeout = Math.round(params.timeout / 1000); + } + } - if ($app === 'Quantumult X') { - // 转换请求参数 - if (params.policy) { - set(params, "opts.policy", params.policy); - } - if (typeof params["auto-redirect"] === "boolean") { - set(params, "opts.redirection", params["auto-redirect"]); - } - // 转换请求体 - if (params.body instanceof ArrayBuffer) { - params.bodyBytes = params.body; - params.body = undefined; - } else if (ArrayBuffer.isView(params.body)) { - params.bodyBytes = params.body.buffer.slice(params.body.byteOffset, params.body.byteLength + params.body.byteOffset); - params.body = undefined; - } else if (params.body) { - params.bodyBytes = undefined; - } - // 发送请求 - return Promise.race([ - await $task.fetch(params).then(response => { - response.ok = /^2\d\d$/.test(response.statusCode); - response.status = response.statusCode; - response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; - if (binaryMimeTypes.includes((response.headers?.["Content-Type"] ?? response.headers?.["content-type"])?.split(";")?.[0])) { - response.body = response.bodyBytes; - } - response.bodyBytes = undefined; - return response; - }, reason => Promise.reject(reason.error)), - new Promise((_, reject) => { - setTimeout(() => { - reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); - }, params.timeout); - }), - ]) - } + if ($app === 'Quantumult X') { + // 转换请求参数 + if (params.policy) { + set(params, 'opts.policy', params.policy); + } + if (typeof params['auto-redirect'] === 'boolean') { + set(params, 'opts.redirection', params['auto-redirect']); + } + // 转换请求体 + if (params.body instanceof ArrayBuffer) { + params.bodyBytes = params.body; + params.body = undefined; + } else if (ArrayBuffer.isView(params.body)) { + params.bodyBytes = params.body.buffer.slice( + params.body.byteOffset, + params.body.byteLength + params.body.byteOffset, + ); + params.body = undefined; + } else if (params.body) { + params.bodyBytes = undefined; + } + // 发送请求 + return Promise.race([ + await $task.fetch(params).then( + (response) => { + response.ok = /^2\d\d$/.test(response.statusCode); + response.status = response.statusCode; + response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; + if ( + binaryMimeTypes.includes( + (response.headers?.['Content-Type'] ?? response.headers?.['content-type'])?.split(';')?.[0], + ) + ) { + response.body = response.bodyBytes; + } + response.bodyBytes = undefined; + return response; + }, + (reason) => Promise.reject(reason.error), + ), + new Promise((_, reject) => { + setTimeout(() => { + reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); + }, params.timeout); + }), + ]); + } - if ($app === "Node.js") { - const nodeFetch = globalThis.fetch ? globalThis.fetch : await import("node-fetch").then(module => module.default); - const fetchCookie = (globalThis as any).fetchCookie ? (globalThis as any).fetchCookie : await import("fetch-cookie").then(module => module.default); - const fetch = fetchCookie(nodeFetch); - // 转换请求参数 - params.timeout = (params.timeout ?? 5) * 1000; - params.redirect = params.redirection ? "follow" : "manual"; - const { url, ...options } = params; - // 发送请求 - return Promise.race([ - await fetch(url, options) - .then(async (response: any) => { - const bodyBytes = await response.arrayBuffer(); - let headers: any; - try { - headers = response.headers.raw(); - } catch { - headers = Array.from(response.headers.entries()).reduce((acc, item) => { - const [key, value] = item as [string, string]; - acc[key] = acc[key] ? [...acc[key], value] : [value]; - return acc; - }, {}); - } - return { - ok: response.ok ?? /^2\d\d$/.test(response.status), - status: response.status, - statusCode: response.status, - statusText: response.statusText, - body: new TextDecoder("utf-8").decode(bodyBytes), - bodyBytes: bodyBytes, - headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, key.toLowerCase() !== "set-cookie" ? (value as any).toString() : value])), - }; - }) - .catch((error: Error) => Promise.reject(error.message)), - new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); - }, params.timeout); - }), - ]); - } + if ($app === 'Node.js') { + const nodeFetch = globalThis.fetch ? globalThis.fetch : await import('node-fetch').then((module) => module.default); + const fetchCookie = (globalThis as any).fetchCookie + ? (globalThis as any).fetchCookie + : await import('fetch-cookie').then((module) => module.default); + const fetch = fetchCookie(nodeFetch); + // 转换请求参数 + params.timeout = (params.timeout ?? 5) * 1000; + params.redirect = params.redirection ? 'follow' : 'manual'; + const { url, ...options } = params; + // 发送请求 + return Promise.race([ + await fetch(url, options) + .then(async (response: any) => { + const bodyBytes = await response.arrayBuffer(); + let headers: any; + try { + headers = response.headers.raw(); + } catch { + headers = Array.from(response.headers.entries()).reduce((acc, item) => { + const [key, value] = item as [string, string]; + acc[key] = acc[key] ? [...acc[key], value] : [value]; + return acc; + }, {}); + } + return { + ok: response.ok ?? /^2\d\d$/.test(response.status), + status: response.status, + statusCode: response.status, + statusText: response.statusText, + body: new TextDecoder('utf-8').decode(bodyBytes), + bodyBytes: bodyBytes, + headers: Object.fromEntries( + Object.entries(headers).map(([key, value]) => [ + key, + key.toLowerCase() !== 'set-cookie' ? (value as any).toString() : value, + ]), + ), + }; + }) + .catch((error: Error) => Promise.reject(error.message)), + new Promise((resolve, reject) => { + setTimeout(() => { + reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); + }, params.timeout); + }), + ]); + } - if ($app === "Loon") { - params.timeout *= 1000; - } - if (params.policy) { - switch ($app) { - case "Loon": - params.node = params.policy; - break; - case "Stash": - set(params, "headers.X-Stash-Selected-Proxy", encodeURI(params.policy)); - break; - case "Shadowrocket": - set(params, "headers.X-Surge-Proxy", params.policy); - break; - default: - break; - } - } - if (typeof params.redirection === "boolean") { - params["auto-redirect"] = params.redirection - }; - // 转换请求体 - if (params.bodyBytes && !params.body) { - params.body = params.bodyBytes; - params.bodyBytes = undefined; - } - // 判断是否请求二进制响应体 - if (binaryMimeTypes.includes((params.headers?.Accept || params.headers?.accept)?.split(";")?.[0] ?? '')) { - params["binary-mode"] = true; - } - return new Promise((resolve, reject) => { - $httpClient[method](params, (error, response, body) => { - if (error) { - reject(error) - } else { - response.ok = /^2\d\d$/.test(response.status); - response.statusCode = response.status; - response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; - if (body) { - response.body = body; - if (params["binary-mode"]) { - response.bodyBytes = body; - } - } - resolve(response); - } - }); - }); + if ($app === 'Loon') { + params.timeout *= 1000; + } + if (params.policy) { + switch ($app) { + case 'Loon': + params.node = params.policy; + break; + case 'Stash': + set(params, 'headers.X-Stash-Selected-Proxy', encodeURI(params.policy)); + break; + case 'Shadowrocket': + set(params, 'headers.X-Surge-Proxy', params.policy); + break; + default: + break; + } + } + if (typeof params.redirection === 'boolean') { + params['auto-redirect'] = params.redirection; + } + // 转换请求体 + if (params.bodyBytes && !params.body) { + params.body = params.bodyBytes; + params.bodyBytes = undefined; + } + // 判断是否请求二进制响应体 + if (binaryMimeTypes.includes((params.headers?.Accept || params.headers?.accept)?.split(';')?.[0] ?? '')) { + params['binary-mode'] = true; + } + return new Promise((resolve, reject) => { + $httpClient[method](params, (error, response, body) => { + if (error) { + reject(error); + } else { + response.ok = /^2\d\d$/.test(response.status); + response.statusCode = response.status; + response.statusText = StatusTexts[response.status as keyof typeof StatusTexts]; + if (body) { + response.body = body; + if (params['binary-mode']) { + response.bodyBytes = body; + } + } + resolve(response); + } + }); + }); } diff --git a/src/polyfill/index.ts b/src/polyfill/index.ts index 3426e27..38535d2 100644 --- a/src/polyfill/index.ts +++ b/src/polyfill/index.ts @@ -1,5 +1,5 @@ -export * from "./Console"; -export * from "./fetch"; -export * from "./Lodash"; -export * from "./StatusTexts"; -export * from "./Storage"; +export * from './Console'; +export * from './fetch'; +export * from './Lodash'; +export * from './StatusTexts'; +export * from './Storage'; diff --git a/test/test.js b/test/test.js index 578c5c7..7bc21e1 100644 --- a/test/test.js +++ b/test/test.js @@ -1,18 +1,29 @@ //import { $app, Console, done, fetch, getStorage, gRPC, Lodash as _, notification, Storage, time, wait } from "@nsnanocat/util"; -import { $app, Console, done, fetch, getStorage, gRPC, Lodash as _, notification, Storage, time, wait } from "../index.js"; +import { + $app, + Console, + Storage, + Lodash as _, + done, + fetch, + gRPC, + getStorage, + notification, + time, + wait, +} from '../index.js'; const request = { - status: 200, - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - status: "ok", - }), - opt: { - method: "GET", - }, - ok: true, + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + status: 'ok', + }), + opt: { + method: 'GET', + }, + ok: true, }; done(request); - diff --git a/tsconfig.json b/tsconfig.json index 87506bf..e12f2dd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,16 @@ { - "compilerOptions": { - "lib": ["ES2021"], - "module": "ESNext", - "target": "ES2021", - "noEmit": true, - "strict": true, - "skipLibCheck": true, - "isolatedModules": true, - "resolveJsonModule": true, - "moduleResolution": "bundler", - "useDefineForClassFields": true, - "allowImportingTsExtensions": true - }, - "include": ["src"] - } - \ No newline at end of file + "compilerOptions": { + "lib": ["ES2021"], + "module": "ESNext", + "target": "ES2021", + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "isolatedModules": true, + "resolveJsonModule": true, + "moduleResolution": "bundler", + "useDefineForClassFields": true, + "allowImportingTsExtensions": true + }, + "include": ["src"] +} From f1fe3be432c49dedc5a9639966e29d2eb62c80cd Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 16:58:17 +0800 Subject: [PATCH 03/31] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=20.npmrc=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=BB=A5=E9=85=8D=E7=BD=AE=20npm=20=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .npmrc | 1 + package-lock.json | 1473 ++++++++++++++++++++++----------------------- 2 files changed, 737 insertions(+), 737 deletions(-) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..214c29d --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ diff --git a/package-lock.json b/package-lock.json index 23ac9be..89828ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,739 +1,738 @@ { - "name": "@nsnanocat/util", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@nsnanocat/util", - "license": "Apache-2.0", - "dependencies": { - "lodash": "^4.17.21" - }, - "devDependencies": { - "@biomejs/biome": "^1.9.2", - "@rslib/core": "^0.2.2", - "@types/lodash": "^4.17.13", - "@types/node": "^22.10.2", - "fetch-cookie": "^3.1.0", - "node-fetch": "^3.3.2", - "typescript": "^5.6.3" - }, - "optionalDependencies": { - "fetch-cookie": "^3.1.0", - "node-fetch": "^3.3.2" - } - }, - "node_modules/@biomejs/biome": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/biome/-/biome-1.9.2.tgz", - "integrity": "sha512-4j2Gfwft8Jqp1X0qLYvK4TEy4xhTo4o6rlvJPsjPeEame8gsmbGQfOPBkw7ur+7/Z/f0HZmCZKqbMvR7vTXQYQ==", - "dev": true, - "hasInstallScript": true, - "bin": { - "biome": "bin/biome" - }, - "engines": { - "node": ">=14.21.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/biome" - }, - "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.2", - "@biomejs/cli-darwin-x64": "1.9.2", - "@biomejs/cli-linux-arm64": "1.9.2", - "@biomejs/cli-linux-arm64-musl": "1.9.2", - "@biomejs/cli-linux-x64": "1.9.2", - "@biomejs/cli-linux-x64-musl": "1.9.2", - "@biomejs/cli-win32-arm64": "1.9.2", - "@biomejs/cli-win32-x64": "1.9.2" - } - }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.2.tgz", - "integrity": "sha512-rbs9uJHFmhqB3Td0Ro+1wmeZOHhAPTL3WHr8NtaVczUmDhXkRDWScaxicG9+vhSLj1iLrW47itiK6xiIJy6vaA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.2.tgz", - "integrity": "sha512-BlfULKijNaMigQ9GH9fqJVt+3JTDOSiZeWOQtG/1S1sa8Lp046JHG3wRJVOvekTPL9q/CNFW1NVG8J0JN+L1OA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.2.tgz", - "integrity": "sha512-T8TJuSxuBDeQCQzxZu2o3OU4eyLumTofhCxxFd3+aH2AEWVMnH7Z/c3QP1lHI5RRMBP9xIJeMORqDQ5j+gVZzw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.2.tgz", - "integrity": "sha512-ZATvbUWhNxegSALUnCKWqetTZqrK72r2RsFD19OK5jXDj/7o1hzI1KzDNG78LloZxftrwr3uI9SqCLh06shSZw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.2.tgz", - "integrity": "sha512-T0cPk3C3Jr2pVlsuQVTBqk2qPjTm8cYcTD9p/wmR9MeVqui1C/xTVfOIwd3miRODFMrJaVQ8MYSXnVIhV9jTjg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.2.tgz", - "integrity": "sha512-CjPM6jT1miV5pry9C7qv8YJk0FIZvZd86QRD3atvDgfgeh9WQU0k2Aoo0xUcPdTnoz0WNwRtDicHxwik63MmSg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.2.tgz", - "integrity": "sha512-2x7gSty75bNIeD23ZRPXyox6Z/V0M71ObeJtvQBhi1fgrvPdtkEuw7/0wEHg6buNCubzOFuN9WYJm6FKoUHfhg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.2", - "resolved": "https://bnpm.byted.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.2.tgz", - "integrity": "sha512-JC3XvdYcjmu1FmAehVwVV0SebLpeNTnO2ZaMdGCSOdS7f8O9Fq14T2P1gTG1Q29Q8Dt1S03hh0IdVpIZykOL8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://bnpm.byted.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@module-federation/runtime": { - "version": "0.5.1", - "resolved": "https://bnpm.byted.org/@module-federation/runtime/-/runtime-0.5.1.tgz", - "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", - "dev": true, - "dependencies": { - "@module-federation/sdk": "0.5.1" - } - }, - "node_modules/@module-federation/runtime-tools": { - "version": "0.5.1", - "resolved": "https://bnpm.byted.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", - "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", - "dev": true, - "dependencies": { - "@module-federation/runtime": "0.5.1", - "@module-federation/webpack-bundler-runtime": "0.5.1" - } - }, - "node_modules/@module-federation/sdk": { - "version": "0.5.1", - "resolved": "https://bnpm.byted.org/@module-federation/sdk/-/sdk-0.5.1.tgz", - "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", - "dev": true - }, - "node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.5.1", - "resolved": "https://bnpm.byted.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", - "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", - "dev": true, - "dependencies": { - "@module-federation/runtime": "0.5.1", - "@module-federation/sdk": "0.5.1" - } - }, - "node_modules/@rsbuild/core": { - "version": "1.1.13", - "resolved": "https://bnpm.byted.org/@rsbuild/core/-/core-1.1.13.tgz", - "integrity": "sha512-XBL2hrin8731W6iTGGL+x3cv07n4vm2D7u6XHRwtQkRfySzAqGx7ThlQLdNX/dJwfsoQrYQuWl/qzaljjXtGtg==", - "dev": true, - "dependencies": { - "@rspack/core": "1.1.8", - "@rspack/lite-tapable": "~1.0.1", - "@swc/helpers": "^0.5.15", - "core-js": "~3.39.0" - }, - "bin": { - "rsbuild": "bin/rsbuild.js" - }, - "engines": { - "node": ">=16.7.0" - } - }, - "node_modules/@rslib/core": { - "version": "0.2.2", - "resolved": "https://bnpm.byted.org/@rslib/core/-/core-0.2.2.tgz", - "integrity": "sha512-u4qKfoO2YAdtoga6NqCDcTfvqyaTZj/L0kZjDrbThMcD51qUb8HiCS8pX5Hwj5v4doGkk+rHeQnw0Ad7HyMPMQ==", - "dev": true, - "dependencies": { - "@rsbuild/core": "~1.1.13", - "rsbuild-plugin-dts": "0.2.2", - "tinyglobby": "^0.2.10" - }, - "bin": { - "rslib": "bin/rslib.js" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@microsoft/api-extractor": "^7", - "typescript": "^5" - }, - "peerDependenciesMeta": { - "@microsoft/api-extractor": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/@rspack/binding": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding/-/binding-1.1.8.tgz", - "integrity": "sha512-+/JzXx1HctfgPj+XtsCTbRkxiaOfAXGZZLEvs7jgp04WgWRSZ5u97WRCePNPvy+sCfOEH/2zw2ZK36Z7oQRGhQ==", - "dev": true, - "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.1.8", - "@rspack/binding-darwin-x64": "1.1.8", - "@rspack/binding-linux-arm64-gnu": "1.1.8", - "@rspack/binding-linux-arm64-musl": "1.1.8", - "@rspack/binding-linux-x64-gnu": "1.1.8", - "@rspack/binding-linux-x64-musl": "1.1.8", - "@rspack/binding-win32-arm64-msvc": "1.1.8", - "@rspack/binding-win32-ia32-msvc": "1.1.8", - "@rspack/binding-win32-x64-msvc": "1.1.8" - } - }, - "node_modules/@rspack/binding-darwin-arm64": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.8.tgz", - "integrity": "sha512-I7avr471ghQ3LAqKm2fuXuJPLgQ9gffn5Q4nHi8rsukuZUtiLDPfYzK1QuupEp2JXRWM1gG5lIbSUOht3cD6Ug==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rspack/binding-darwin-x64": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.8.tgz", - "integrity": "sha512-vfqf/c+mcx8rr1M8LnqKmzDdnrgguflZnjGerBLjNerAc+dcUp3lCvNxRIvZ2TkSZZBW8BpCMgjj3n70CZ4VLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rspack/binding-linux-arm64-gnu": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.8.tgz", - "integrity": "sha512-lZlO/rAJSeozi+qtVLkGSXfe+riPawCwM4FsrflELfNlvvEXpANwtrdJ+LsaNVXcgvhh50ZX2KicTdmx9G2b6Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-arm64-musl": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.8.tgz", - "integrity": "sha512-bX7exULSZwy8xtDh6Z65b6sRC4uSxGuyvSLCEKyhmG6AnJkg0gQMxk3hoO0hWnyGEZgdJEn+jEhk0fjl+6ZRAQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-x64-gnu": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.8.tgz", - "integrity": "sha512-2Prw2USgTJ3aLdLExfik8pAwAHbX4MZrACBGEmR7Vbb56kLjC+++fXkciRc50pUDK4JFr1VQ7eNZrJuDR6GG6Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-x64-musl": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.8.tgz", - "integrity": "sha512-bnVGB/mQBKEdzOU/CPmcOE3qEXxGOGGW7/i6iLl2MamVOykJq8fYjL9j86yi6L0r009ja16OgWckykQGc4UqGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-win32-arm64-msvc": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.8.tgz", - "integrity": "sha512-u+na3gxhzeksm4xZyAzn1+XWo5a5j7hgWA/KcFPDQ8qQNkRknx4jnQMxVtcZ9pLskAYV4AcOV/AIximx7zvv8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/binding-win32-ia32-msvc": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.8.tgz", - "integrity": "sha512-FijUxym1INd5fFHwVCLuVP8XEAb4Sk1sMwEEQUlugiDra9ZsLaPw4OgPGxbxkD6SB0DeUz9Zq46Xbcf6d3OgfA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/binding-win32-x64-msvc": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.8.tgz", - "integrity": "sha512-SBzIcND4qpDt71jlu1MCDxt335tqInT3YID9V4DoQ4t8wgM/uad7EgKOWKTK6vc2RRaOIShfS2XzqjNUxPXh4w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/core": { - "version": "1.1.8", - "resolved": "https://bnpm.byted.org/@rspack/core/-/core-1.1.8.tgz", - "integrity": "sha512-pcZtcj5iXLCuw9oElTYC47bp/RQADm/MMEb3djHdwJuSlFWfWPQi5QFgJ/lJAxIW9UNHnTFrYtytycfjpuoEcA==", - "dev": true, - "dependencies": { - "@module-federation/runtime-tools": "0.5.1", - "@rspack/binding": "1.1.8", - "@rspack/lite-tapable": "1.0.1", - "caniuse-lite": "^1.0.30001616" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.1" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@rspack/lite-tapable": { - "version": "1.0.1", - "resolved": "https://bnpm.byted.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", - "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://bnpm.byted.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "dev": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@types/lodash": { - "version": "4.17.13", - "resolved": "https://bnpm.byted.org/@types/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", - "dev": true - }, - "node_modules/@types/node": { - "version": "22.10.2", - "resolved": "https://bnpm.byted.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", - "dev": true, - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001690", - "resolved": "https://bnpm.byted.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", - "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/core-js": { - "version": "3.39.0", - "resolved": "https://bnpm.byted.org/core-js/-/core-js-3.39.0.tgz", - "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://bnpm.byted.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://bnpm.byted.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://bnpm.byted.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/fetch-cookie": { - "version": "3.1.0", - "resolved": "https://bnpm.byted.org/fetch-cookie/-/fetch-cookie-3.1.0.tgz", - "integrity": "sha512-s/XhhreJpqH0ftkGVcQt8JE9bqk+zRn4jF5mPJXWZeQMCI5odV9K+wEWYbnzFPHgQZlvPSMjS4n4yawWE8RINw==", - "dev": true, - "dependencies": { - "set-cookie-parser": "^2.4.8", - "tough-cookie": "^5.0.0" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://bnpm.byted.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://bnpm.byted.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://bnpm.byted.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://bnpm.byted.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://bnpm.byted.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://bnpm.byted.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://bnpm.byted.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/rsbuild-plugin-dts": { - "version": "0.2.2", - "resolved": "https://bnpm.byted.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.2.2.tgz", - "integrity": "sha512-RwkVcMwig1+UHkVJFaD6tagjxZOQqIenbkLS+J85bEdKO/ra+YiLC1Gq3DItEv/hU02u5WPgJmQhaQWKb17T9w==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.17", - "picocolors": "1.1.1", - "tinyglobby": "^0.2.10" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@microsoft/api-extractor": "^7", - "@rsbuild/core": "1.x", - "typescript": "^5" - }, - "peerDependenciesMeta": { - "@microsoft/api-extractor": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://bnpm.byted.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "dev": true - }, - "node_modules/tinyglobby": { - "version": "0.2.10", - "resolved": "https://bnpm.byted.org/tinyglobby/-/tinyglobby-0.2.10.tgz", - "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", - "dev": true, - "dependencies": { - "fdir": "^6.4.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/tldts": { - "version": "6.1.70", - "resolved": "https://bnpm.byted.org/tldts/-/tldts-6.1.70.tgz", - "integrity": "sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==", - "dev": true, - "dependencies": { - "tldts-core": "^6.1.70" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.70", - "resolved": "https://bnpm.byted.org/tldts-core/-/tldts-core-6.1.70.tgz", - "integrity": "sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==", - "dev": true - }, - "node_modules/tough-cookie": { - "version": "5.0.0", - "resolved": "https://bnpm.byted.org/tough-cookie/-/tough-cookie-5.0.0.tgz", - "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", - "dev": true, - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://bnpm.byted.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://bnpm.byted.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://bnpm.byted.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "dev": true, - "engines": { - "node": ">= 8" - } - } - } + "name": "@nsnanocat/util", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@nsnanocat/util", + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.2", + "@rslib/core": "^0.2.2", + "@types/lodash": "^4.17.13", + "@types/node": "^22.10.2", + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2", + "typescript": "^5.6.3" + }, + "optionalDependencies": { + "fetch-cookie": "^3.1.0", + "node-fetch": "^3.3.2" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "dev": true, + "hasInstallScript": true, + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@rsbuild/core": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.1.13.tgz", + "integrity": "sha512-XBL2hrin8731W6iTGGL+x3cv07n4vm2D7u6XHRwtQkRfySzAqGx7ThlQLdNX/dJwfsoQrYQuWl/qzaljjXtGtg==", + "dev": true, + "dependencies": { + "@rspack/core": "1.1.8", + "@rspack/lite-tapable": "~1.0.1", + "@swc/helpers": "^0.5.15", + "core-js": "~3.39.0" + }, + "bin": { + "rsbuild": "bin/rsbuild.js" + }, + "engines": { + "node": ">=16.7.0" + } + }, + "node_modules/@rslib/core": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@rslib/core/-/core-0.2.2.tgz", + "integrity": "sha512-u4qKfoO2YAdtoga6NqCDcTfvqyaTZj/L0kZjDrbThMcD51qUb8HiCS8pX5Hwj5v4doGkk+rHeQnw0Ad7HyMPMQ==", + "dev": true, + "dependencies": { + "@rsbuild/core": "~1.1.13", + "rsbuild-plugin-dts": "0.2.2", + "tinyglobby": "^0.2.10" + }, + "bin": { + "rslib": "bin/rslib.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@rspack/binding": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.8.tgz", + "integrity": "sha512-+/JzXx1HctfgPj+XtsCTbRkxiaOfAXGZZLEvs7jgp04WgWRSZ5u97WRCePNPvy+sCfOEH/2zw2ZK36Z7oQRGhQ==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.8", + "@rspack/binding-darwin-x64": "1.1.8", + "@rspack/binding-linux-arm64-gnu": "1.1.8", + "@rspack/binding-linux-arm64-musl": "1.1.8", + "@rspack/binding-linux-x64-gnu": "1.1.8", + "@rspack/binding-linux-x64-musl": "1.1.8", + "@rspack/binding-win32-arm64-msvc": "1.1.8", + "@rspack/binding-win32-ia32-msvc": "1.1.8", + "@rspack/binding-win32-x64-msvc": "1.1.8" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.8.tgz", + "integrity": "sha512-I7avr471ghQ3LAqKm2fuXuJPLgQ9gffn5Q4nHi8rsukuZUtiLDPfYzK1QuupEp2JXRWM1gG5lIbSUOht3cD6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.8.tgz", + "integrity": "sha512-vfqf/c+mcx8rr1M8LnqKmzDdnrgguflZnjGerBLjNerAc+dcUp3lCvNxRIvZ2TkSZZBW8BpCMgjj3n70CZ4VLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.8.tgz", + "integrity": "sha512-lZlO/rAJSeozi+qtVLkGSXfe+riPawCwM4FsrflELfNlvvEXpANwtrdJ+LsaNVXcgvhh50ZX2KicTdmx9G2b6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.8.tgz", + "integrity": "sha512-bX7exULSZwy8xtDh6Z65b6sRC4uSxGuyvSLCEKyhmG6AnJkg0gQMxk3hoO0hWnyGEZgdJEn+jEhk0fjl+6ZRAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.8.tgz", + "integrity": "sha512-2Prw2USgTJ3aLdLExfik8pAwAHbX4MZrACBGEmR7Vbb56kLjC+++fXkciRc50pUDK4JFr1VQ7eNZrJuDR6GG6Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.8.tgz", + "integrity": "sha512-bnVGB/mQBKEdzOU/CPmcOE3qEXxGOGGW7/i6iLl2MamVOykJq8fYjL9j86yi6L0r009ja16OgWckykQGc4UqGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.8.tgz", + "integrity": "sha512-u+na3gxhzeksm4xZyAzn1+XWo5a5j7hgWA/KcFPDQ8qQNkRknx4jnQMxVtcZ9pLskAYV4AcOV/AIximx7zvv8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.8.tgz", + "integrity": "sha512-FijUxym1INd5fFHwVCLuVP8XEAb4Sk1sMwEEQUlugiDra9ZsLaPw4OgPGxbxkD6SB0DeUz9Zq46Xbcf6d3OgfA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.8.tgz", + "integrity": "sha512-SBzIcND4qpDt71jlu1MCDxt335tqInT3YID9V4DoQ4t8wgM/uad7EgKOWKTK6vc2RRaOIShfS2XzqjNUxPXh4w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.8.tgz", + "integrity": "sha512-pcZtcj5iXLCuw9oElTYC47bp/RQADm/MMEb3djHdwJuSlFWfWPQi5QFgJ/lJAxIW9UNHnTFrYtytycfjpuoEcA==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.8", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fetch-cookie": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-3.1.0.tgz", + "integrity": "sha512-s/XhhreJpqH0ftkGVcQt8JE9bqk+zRn4jF5mPJXWZeQMCI5odV9K+wEWYbnzFPHgQZlvPSMjS4n4yawWE8RINw==", + "dev": true, + "dependencies": { + "set-cookie-parser": "^2.4.8", + "tough-cookie": "^5.0.0" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rsbuild-plugin-dts": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.2.2.tgz", + "integrity": "sha512-RwkVcMwig1+UHkVJFaD6tagjxZOQqIenbkLS+J85bEdKO/ra+YiLC1Gq3DItEv/hU02u5WPgJmQhaQWKb17T9w==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.17", + "picocolors": "1.1.1", + "tinyglobby": "^0.2.10" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7", + "@rsbuild/core": "1.x", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "dev": true + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.70", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.70.tgz", + "integrity": "sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==", + "dev": true, + "dependencies": { + "tldts-core": "^6.1.70" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.70", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.70.tgz", + "integrity": "sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", + "dev": true, + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + } + } } From 867561c9c2e536feba18a4c357220a5718434f70 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:06:57 +0800 Subject: [PATCH 04/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0$app=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=BB=A5=E5=8C=85=E5=90=AB=E6=9B=B4=E5=A4=9A=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 407268a..a888f9a 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -1,7 +1,7 @@ /** * Current app name */ -export const $app = (() => { +export const $app: "Quantumult X" | "Loon" | "Shadowrocket" | "Egern" | "Surge" | "Stash" | "Node.js" | undefined = (() => { if ('$task' in globalThis) { return 'Quantumult X'; } From 3182f55b769eac94bcc9683bd2e189d386e64d46 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:16:38 +0800 Subject: [PATCH 05/31] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E6=8B=89=E5=8F=96=E8=AF=B7=E6=B1=82=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=8C=E5=8F=91=E5=B8=83=E9=A2=84=E8=A7=88=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-package.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index fda9f5e..b3ee91f 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -5,9 +5,14 @@ on: # Sequence of patterns matched against refs/tags tags: - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 + pull_request: + types: + - opened + - synchronize # Trigger on every push to the PR jobs: publish: + if: github.event_name == 'push' runs-on: ubuntu-latest permissions: packages: write @@ -31,3 +36,25 @@ jobs: - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ matrix.registry == 'https://registry.npmjs.org' && secrets.NPM_TOKEN || secrets.GITHUB_TOKEN }} + + preview: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: "https://registry.npmjs.org" + - run: npm ci + - name: Update package version for preview + run: | + PR_NUMBER=${{ github.event.number }} + COMMIT_SHA=${{ github.sha }} + npm version $(jq -r '.version' package.json)-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} + - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From a4ccbe188d78ac25d33217f169667f9a9485b3fb Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:19:20 +0800 Subject: [PATCH 06/31] =?UTF-8?q?chore:=20=E7=A7=BB=E9=99=A4=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=A2=84=E8=A7=88=E4=BD=9C=E4=B8=9A=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E6=9D=83=E9=99=90=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-package.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index b3ee91f..65cc2bd 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -40,9 +40,6 @@ jobs: preview: if: github.event_name == 'pull_request' runs-on: ubuntu-latest - permissions: - packages: write - contents: read steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From abc5541199e2c99fba4be276868166fda2a20f7b Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:19:57 +0800 Subject: [PATCH 07/31] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=A2=84=E8=A7=88=E4=BD=9C=E4=B8=9A=E7=9A=84=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=AE=BE=E7=BD=AE=E4=BB=A5=E6=94=AF=E6=8C=81=E5=8C=85?= =?UTF-8?q?=E5=86=99=E5=85=A5=E5=92=8C=E5=86=85=E5=AE=B9=E8=AF=BB=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-package.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 65cc2bd..b3ee91f 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -40,6 +40,9 @@ jobs: preview: if: github.event_name == 'pull_request' runs-on: ubuntu-latest + permissions: + packages: write + contents: read steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From 1286fdbb09cac4b5c470018e62cae009e08ee265 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:23:09 +0800 Subject: [PATCH 08/31] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=A2=84=E8=A7=88=E7=89=88=E6=9C=AC=E7=9A=84=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index b3ee91f..b64a246 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -54,7 +54,7 @@ jobs: run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} - npm version $(jq -r '.version' package.json)-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} + npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 5515b5f483bcdc08562aed22c6b1ad8b1dfde575 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:24:34 +0800 Subject: [PATCH 09/31] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8B=89=E5=8F=96=E8=AF=B7=E6=B1=82=E7=9A=84=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 29 +++++++++++++++++++++++++++ .github/workflows/release-package.yml | 29 +-------------------------- 2 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 0000000..3447af5 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,29 @@ +name: preview + +on: + pull_request: + types: + - opened + - synchronize # Trigger on every push to the PR + +jobs: + preview: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: "https://registry.npmjs.org" + - run: npm ci + - name: Update package version for preview + run: | + PR_NUMBER=${{ github.event.number }} + COMMIT_SHA=${{ github.sha }} + npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} + - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index b64a246..1148c1a 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -5,14 +5,9 @@ on: # Sequence of patterns matched against refs/tags tags: - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 - pull_request: - types: - - opened - - synchronize # Trigger on every push to the PR jobs: publish: - if: github.event_name == 'push' runs-on: ubuntu-latest permissions: packages: write @@ -35,26 +30,4 @@ jobs: - run: npm ci - run: npm publish --access public env: - NODE_AUTH_TOKEN: ${{ matrix.registry == 'https://registry.npmjs.org' && secrets.NPM_TOKEN || secrets.GITHUB_TOKEN }} - - preview: - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - registry-url: "https://registry.npmjs.org" - - run: npm ci - - name: Update package version for preview - run: | - PR_NUMBER=${{ github.event.number }} - COMMIT_SHA=${{ github.sha }} - npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} - - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ matrix.registry == 'https://registry.npmjs.org' && secrets.NPM_TOKEN || secrets.GITHUB_TOKEN }} \ No newline at end of file From 0a00ec422b2df3be3139ca5aaf3e28242ce06a7b Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:26:16 +0800 Subject: [PATCH 10/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E7=89=88=E6=9C=AC=E5=91=BD=E4=BB=A4=E4=BB=A5=E7=A6=81?= =?UTF-8?q?=E7=94=A8=20Git=20=E6=A0=87=E7=AD=BE=E7=89=88=E6=9C=AC=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 3447af5..3c787df 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -23,7 +23,7 @@ jobs: run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} - npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} + npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} --no-git-tag-version - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From e78ab8b6f4878e07f28e0234541b2c73fecc0974 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:29:07 +0800 Subject: [PATCH 11/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E7=AE=80=E5=8C=96?= =?UTF-8?q?=20npm=20=E5=8F=91=E5=B8=83=E6=A0=87=E7=AD=BE=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 3c787df..7311c6d 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -24,6 +24,6 @@ jobs: PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} --no-git-tag-version - - run: npm publish --tag preview-${{ github.event.number }}-${{ github.sha }} --access public + - run: npm publish --tag preview-${{ github.event.number }} --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 9c195f5cd46ca614dc2d7193dbfeb366fc5bfbad Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:31:21 +0800 Subject: [PATCH 12/31] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=20.npmrc=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=BB=A5=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84=20npm=20=E6=B3=A8=E5=86=8C=E8=A1=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .npmrc | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .npmrc diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 214c29d..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -registry=https://registry.npmjs.org/ From 6b48c5b94ae2c232f0c30f7b44bd66575ce804ad Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:31:47 +0800 Subject: [PATCH 13/31] =?UTF-8?q?chore:=20=E7=A7=BB=E9=99=A4=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=20npm=20?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E8=A1=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 7311c6d..7a3de5e 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -17,7 +17,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20 - registry-url: "https://registry.npmjs.org" - run: npm ci - name: Update package version for preview run: | From 3a49d0e074615b06e1427f37fdaf5a064ec76ed0 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:33:56 +0800 Subject: [PATCH 14/31] =?UTF-8?q?chore:=20=E5=9C=A8=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E6=B7=BB=E5=8A=A0=20npm=20?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E8=A1=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 7a3de5e..7311c6d 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -17,6 +17,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20 + registry-url: "https://registry.npmjs.org" - run: npm ci - name: Update package version for preview run: | From 79f7ed312e47c28ce3696af90bd70f80b205eb71 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:36:29 +0800 Subject: [PATCH 15/31] =?UTF-8?q?fix:=20=E5=9C=A8=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E6=B7=BB=E5=8A=A0=20NPM=5F?= =?UTF-8?q?TOKEN=20=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E4=BB=A5=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=20npm=20=E5=8F=91=E5=B8=83=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 7311c6d..bc36fc1 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -27,3 +27,4 @@ jobs: - run: npm publish --tag preview-${{ github.event.number }} --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} From 667eab25f7b8f17d8a1038e8e12fdfd12cf2287f Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:37:50 +0800 Subject: [PATCH 16/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20NODE=5FAUTH=5FTOKEN=20=E8=BF=9B=E8=A1=8C=20npm=20=E5=8F=91?= =?UTF-8?q?=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index bc36fc1..e4db61e 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -19,12 +19,11 @@ jobs: node-version: 20 registry-url: "https://registry.npmjs.org" - run: npm ci - - name: Update package version for preview - run: | + - run: echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} --no-git-tag-version - - run: npm publish --tag preview-${{ github.event.number }} --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: npm publish --tag preview-${{ github.event.number }} --access public \ No newline at end of file From 2c186bb6ae1aefbe84b623d197c6eece7ceb8698 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:43:50 +0800 Subject: [PATCH 17/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20secrets.NODE=5FAUTH=5FTOKEN=20=E8=BF=9B=E8=A1=8C=20npm=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index e4db61e..9ac1fab 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -19,9 +19,7 @@ jobs: node-version: 20 registry-url: "https://registry.npmjs.org" - run: npm ci - - run: echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NODE_AUTH_TOKEN }}" > ~/.npmrc - run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} From e728d1e174341ac28a38cf8e10e255922c195b64 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 17:49:29 +0800 Subject: [PATCH 18/31] =?UTF-8?q?fix:=20=E5=9C=A8=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E5=B0=86=20npm=20=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E7=9A=84=20NODE=5FAUTH=5FTOKEN=20=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=A7=BB=E8=87=B3=E8=BF=90=E8=A1=8C=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 9ac1fab..4a86f12 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -19,9 +19,10 @@ jobs: node-version: 20 registry-url: "https://registry.npmjs.org" - run: npm ci - - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NODE_AUTH_TOKEN }}" > ~/.npmrc - run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} --no-git-tag-version - - run: npm publish --tag preview-${{ github.event.number }} --access public \ No newline at end of file + - run: npm publish --tag preview-${{ github.event.number }} --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} \ No newline at end of file From 111093d65c4f3c67dac7dca33d79223fe67a3030 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 18:42:47 +0800 Subject: [PATCH 19/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=20npm=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=91=BD=E4=BB=A4=E4=BB=A5=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=20PR=20=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 4a86f12..27aa185 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -22,7 +22,7 @@ jobs: - run: | PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} - npm version 0.0.0-preview-PR${PR_NUMBER}-${COMMIT_SHA::7} --no-git-tag-version + npm version 0.0.0-preview-${COMMIT_SHA::7} --no-git-tag-version - run: npm publish --tag preview-${{ github.event.number }} --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} \ No newline at end of file From 2361715098e11957aab172f15aef5a73be2fa05f Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Mon, 30 Dec 2024 18:45:51 +0800 Subject: [PATCH 20/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20NPM=5FTOKEN=20=E6=9B=BF=E4=BB=A3=20NODE=5FAUTH=5FTOKEN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 27aa185..24a3f8b 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -20,9 +20,8 @@ jobs: registry-url: "https://registry.npmjs.org" - run: npm ci - run: | - PR_NUMBER=${{ github.event.number }} COMMIT_SHA=${{ github.sha }} npm version 0.0.0-preview-${COMMIT_SHA::7} --no-git-tag-version - run: npm publish --tag preview-${{ github.event.number }} --access public env: - NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} \ No newline at end of file + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file From 29b43228b15d29fb7282008842b3bbe56cac5547 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Thu, 2 Jan 2025 15:47:47 +0800 Subject: [PATCH 21/31] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20lodash?= =?UTF-8?q?=20=E4=BE=9D=E8=B5=96=EF=BC=8C=E4=BD=BF=E7=94=A8=20type-fest=20?= =?UTF-8?q?=E5=92=8C=E8=87=AA=E5=AE=9A=E4=B9=89=20polyfill=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 25 +++++----- package.json | 16 +++++-- rslib.config.ts | 6 --- src/getStorage.ts | 2 +- src/lib/done.ts | 2 +- src/polyfill/Lodash.ts | 104 +++++++++++++++++++++++++++++++++++++--- src/polyfill/Storage.ts | 2 +- src/polyfill/fetch.ts | 2 +- 8 files changed, 125 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89828ce..2ee62b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,12 +7,11 @@ "name": "@nsnanocat/util", "license": "Apache-2.0", "dependencies": { - "lodash": "^4.17.21" + "type-fest": "^4.31.0" }, "devDependencies": { "@biomejs/biome": "^1.9.2", "@rslib/core": "^0.2.2", - "@types/lodash": "^4.17.13", "@types/node": "^22.10.2", "fetch-cookie": "^3.1.0", "node-fetch": "^3.3.2", @@ -441,12 +440,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@types/lodash": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", - "dev": true - }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -555,11 +548,6 @@ "node": ">=12.20.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -706,6 +694,17 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, + "node_modules/type-fest": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.31.0.tgz", + "integrity": "sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", diff --git a/package.json b/package.json index 13ae7c1..209b7e4 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,14 @@ "type": "module", "author": "VirgilClyne ", "homepage": "https://NSNanoCat.github.io/util", - "keywords": ["loon", "quantumult", "surge", "shadowrocket", "stash", "egern"], + "keywords": [ + "loon", + "quantumult", + "surge", + "shadowrocket", + "stash", + "egern" + ], "license": "Apache-2.0", "bugs": "https://github.com/NSNanoCat/util/issues", "main": "./dist/index.cjs", @@ -43,14 +50,15 @@ "type": "git", "url": "https://github.com/NSNanoCat/util.git" }, - "files": ["dist"], + "files": [ + "dist" + ], "dependencies": { - "lodash": "^4.17.21" + "type-fest": "^4.31.0" }, "devDependencies": { "@biomejs/biome": "^1.9.2", "@rslib/core": "^0.2.2", - "@types/lodash": "^4.17.13", "@types/node": "^22.10.2", "fetch-cookie": "^3.1.0", "node-fetch": "^3.3.2", diff --git a/rslib.config.ts b/rslib.config.ts index 3242a28..855b881 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -9,11 +9,5 @@ export default defineConfig({ entry: { index: './src/**', }, - transformImport: [ - { - libraryName: 'lodash', - customName: 'lodash/{{ member }}', - }, - ], }, }); diff --git a/src/getStorage.ts b/src/getStorage.ts index 415c668..3b00e5a 100644 --- a/src/getStorage.ts +++ b/src/getStorage.ts @@ -1,4 +1,4 @@ -import { set } from 'lodash'; +import { set } from './polyfill/Lodash'; import { Storage } from './polyfill/Storage'; type Database = Record; diff --git a/src/lib/done.ts b/src/lib/done.ts index dee3e1c..8e2449c 100644 --- a/src/lib/done.ts +++ b/src/lib/done.ts @@ -1,4 +1,4 @@ -import { pick, set } from 'lodash'; +import { pick, set } from '../polyfill/Lodash'; import { Console } from '../polyfill/Console'; import { StatusTexts } from '../polyfill/StatusTexts'; import { $app } from './app'; diff --git a/src/polyfill/Lodash.ts b/src/polyfill/Lodash.ts index 0a6b9eb..d7fa37a 100644 --- a/src/polyfill/Lodash.ts +++ b/src/polyfill/Lodash.ts @@ -1,12 +1,102 @@ -import { get, escape as lodashEscape, unescape as lodashUnescape, omit, pick, set, toPath, unset } from 'lodash'; +import type { ToPath } from 'type-fest/source/get'; +import type { Get, Paths, PickDeep } from 'type-fest'; + +const ESCAPE_MAP = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', +} as const; + +const UNESCAPE_MAP = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", +} as const; + +const ESCAPE_REGEX = /[&<>"']/g; +const UNESCAPE_REGEX = /&(amp|lt|gt|quot|#39);/g; + +// biome-ignore lint/suspicious/noShadowRestrictedNames: +export const escape = (str: string) => { + if (!ESCAPE_REGEX.test(str)) return str; + + ESCAPE_REGEX.lastIndex = 0; + return str.replace(ESCAPE_REGEX, (match) => ESCAPE_MAP[match as keyof typeof ESCAPE_MAP]); +}; + +// biome-ignore lint/suspicious/noShadowRestrictedNames: +export const unescape = (str: string) => { + if (!UNESCAPE_REGEX.test(str)) return str; + + UNESCAPE_REGEX.lastIndex = 0; + return str.replace(UNESCAPE_REGEX, (match) => UNESCAPE_MAP[match as keyof typeof UNESCAPE_MAP]); +}; + +export const toPath = (value: T) => + value + .replace(/\[(\d+)\]/g, '.$1') + .split('.') + .filter(Boolean) as ToPath; + +export const get = (obj: T, path: Path, defaultValue?: Get) => { + const getPath = Array.isArray(path) ? path : toPath(path); + const result = getPath.reduce((previousValue, currentValue) => Object(previousValue)[currentValue], obj); + return result === undefined ? defaultValue : result; +}; + +export const set = (obj: T, path: Path, value: Get) => { + const setPath = (Array.isArray(path) ? path : toPath(path)) as string[]; + + setPath.slice(0, -1).reduce((prev, key, index) => { + if (typeof prev[key] !== 'object' || prev[key] === null) { + prev[key] = /^\d+$/.test(setPath[index + 1]) ? [] : {}; + } + return prev[key]; + }, obj as Record)[setPath[setPath.length - 1]] = value; + + return obj; +}; + +export const unset = (obj: T, path: Path) => { + const unsetPath = Array.isArray(path) ? path : toPath(path); + return unsetPath.reduce((previousValue, currentValue, currentIndex) => { + if (currentIndex === path.length - 1) { + delete previousValue[currentValue as Path]; + return true; + } + return Object(previousValue)[currentValue]; + }, obj); +} + +export const omit = & string>>(obj: T, paths: PathArray) => { + const result = { ...obj }; + paths.forEach((path) => unset(result, path)); + return result as Omit; +}; + +export const pick = & string>>(obj: T, paths: PathArray) => { + return Object.entries(obj) + .filter(([key]) => paths.includes(key as PathArray[number])) + .reduce( + (result, [key, value]) => { + (result as any)[key] = value; + return result; + }, + {} as PickDeep + ); +} export const Lodash = { - escape: lodashEscape, + escape, + unescape, + toPath, get, - omit, - pick, set, - toPath, - unescape: lodashUnescape, unset, -}; + omit, + pick, +} \ No newline at end of file diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts index 715a1f7..00904cc 100644 --- a/src/polyfill/Storage.ts +++ b/src/polyfill/Storage.ts @@ -1,4 +1,4 @@ -import { get, set, unset } from 'lodash'; +import { get, set, unset } from './Lodash'; import { $app } from '../lib/app'; declare const $persistentStore: { diff --git a/src/polyfill/fetch.ts b/src/polyfill/fetch.ts index bcefe9a..86323c3 100644 --- a/src/polyfill/fetch.ts +++ b/src/polyfill/fetch.ts @@ -1,4 +1,4 @@ -import { set } from 'lodash'; +import { set } from './Lodash'; import { $app } from '../lib/app'; import { StatusTexts } from './StatusTexts'; From faba88e666c222a6ae0bf59992d334d5334eaf47 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Fri, 3 Jan 2025 14:54:36 +0800 Subject: [PATCH 22/31] =?UTF-8?q?refactor:=20=E5=B0=86=20Storage=20?= =?UTF-8?q?=E7=B1=BB=E4=B8=AD=E7=9A=84=E6=96=87=E4=BB=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E5=BC=82=E6=AD=A5=E5=8A=A0=E8=BD=BD=E5=92=8C?= =?UTF-8?q?=E5=86=99=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polyfill/Storage.ts | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts index 00904cc..1f11525 100644 --- a/src/polyfill/Storage.ts +++ b/src/polyfill/Storage.ts @@ -24,9 +24,9 @@ export class StorageClass { constructor() { if ($app === 'Node.js') { - const fs = require('node:fs'); - const path = require('node:path'); - this.data = this.#loadData(this.dataFile, fs, path); + this.#loadData(this.dataFile).then((res) => { + this.data = res; + }) } } @@ -147,7 +147,20 @@ export class StorageClass { } } - #loadData(dataFile: string, fs: any, path: any): StorageData { + async #getNodeModule() { + if ($app === 'Node.js') { + const fs = await import('node:fs') + const path = await import('node:path') + return { fs, path } + } + return null; + } + + async #loadData(dataFile: string): Promise { + const { fs, path } = await this.#getNodeModule() ?? {}; + if (!fs || !path) { + return {}; + } const curDirDataFilePath = path.resolve(dataFile); const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); if (fs.existsSync(curDirDataFilePath)) { @@ -159,13 +172,13 @@ export class StorageClass { return {}; } - #writeData(dataFile: string): void { - if ($app === 'Node.js') { - const fs = require('node:fs'); - const path = require('node:path'); - const dataFilePath = path.resolve(dataFile); - fs.writeFileSync(dataFilePath, JSON.stringify(this.data), 'utf-8'); + async #writeData(dataFile: string): Promise { + const { fs, path } = await this.#getNodeModule() ?? {}; + if (!fs || !path) { + return } + const dataFilePath = path.resolve(dataFile); + fs.writeFileSync(dataFilePath, JSON.stringify(this.data), 'utf-8'); } } From e3a1dbbbe218a18b1af7522f5103970f73c987c6 Mon Sep 17 00:00:00 2001 From: "baran.wang" Date: Fri, 3 Jan 2025 15:38:56 +0800 Subject: [PATCH 23/31] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20StorageClass?= =?UTF-8?q?=20=E4=B8=AD=E7=9A=84=20Node.js=20=E6=A8=A1=E5=9D=97=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E6=96=B9=E5=BC=8F=E4=BB=A5=E7=AC=A6=E5=90=88=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polyfill/Storage.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts index 1f11525..c2d24fd 100644 --- a/src/polyfill/Storage.ts +++ b/src/polyfill/Storage.ts @@ -149,8 +149,10 @@ export class StorageClass { async #getNodeModule() { if ($app === 'Node.js') { - const fs = await import('node:fs') - const path = await import('node:path') + // biome-ignore lint/style/useNodejsImportProtocol: + const fs = await import('fs') + // biome-ignore lint/style/useNodejsImportProtocol: + const path = await import('path') return { fs, path } } return null; From 3805ede57d7cb738cc4cfdb1112f84aba87f782e Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:33:37 +0800 Subject: [PATCH 24/31] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Node.js=20?= =?UTF-8?q?=E7=9A=84=20fetch=20polyfill=20=E5=92=8C=20Storage=20=E7=B1=BB?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 11 +- package-lock.json | 599 ++++++++++++++++++++++++++++++++++ package.json | 31 +- rslib.config.ts | 46 ++- src/lib/app.ts | 47 +-- src/polyfill/Lodash.ts | 23 +- src/polyfill/Storage.d.ts | 8 + src/polyfill/Storage.mjs | 185 +++++++++++ src/polyfill/Storage.ts | 188 ----------- src/polyfill/fetch-node.d.ts | 1 + src/polyfill/fetch-node.mjs | 8 + src/polyfill/fetch.ts | 10 +- 12 files changed, 904 insertions(+), 253 deletions(-) create mode 100644 src/polyfill/Storage.d.ts create mode 100644 src/polyfill/Storage.mjs delete mode 100644 src/polyfill/Storage.ts create mode 100644 src/polyfill/fetch-node.d.ts create mode 100644 src/polyfill/fetch-node.mjs diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 24a3f8b..dc49b60 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -12,6 +12,7 @@ jobs: permissions: packages: write contents: read + issues: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -24,4 +25,12 @@ jobs: npm version 0.0.0-preview-${COMMIT_SHA::7} --no-git-tag-version - run: npm publish --tag preview-${{ github.event.number }} --access public env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: | + VERSION=$(node -p "require('./package.json').version") + echo "npm version is: $VERSION" + PR_NUMBER=${{ github.event.pull_request.number }} + COMMENT_BODY="The npm version is: $VERSION" + gh pr comment $PR_NUMBER --body "$COMMENT_BODY" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2ee62b3..2262765 100644 --- a/package-lock.json +++ b/package-lock.json @@ -183,6 +183,82 @@ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, + "node_modules/@microsoft/api-extractor": { + "version": "7.48.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.1.tgz", + "integrity": "sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@microsoft/api-extractor-model": "7.30.1", + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.10.1", + "@rushstack/rig-package": "0.5.3", + "@rushstack/terminal": "0.14.4", + "@rushstack/ts-command-line": "4.23.2", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.1.tgz", + "integrity": "sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.10.1" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", + "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@microsoft/tsdoc": "0.15.1", + "ajv": "~8.12.0", + "jju": "~1.4.0", + "resolve": "~1.22.2" + } + }, "node_modules/@module-federation/runtime": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", @@ -431,6 +507,96 @@ "node": ">=16.0.0" } }, + "node_modules/@rushstack/node-core-library": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", + "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/node-core-library/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@rushstack/rig-package": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", + "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/terminal": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.4.tgz", + "integrity": "sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@rushstack/node-core-library": "5.10.1", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.2.tgz", + "integrity": "sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@rushstack/terminal": "0.14.4", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" + } + }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -440,6 +606,14 @@ "tslib": "^2.8.0" } }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -449,6 +623,90 @@ "undici-types": "~6.20.0" } }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001690", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", @@ -469,6 +727,14 @@ } ] }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/core-js": { "version": "3.39.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", @@ -489,6 +755,14 @@ "node": ">= 12" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/fdir": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", @@ -548,6 +822,143 @@ "node": ">=12.20.0" } }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "optional": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optional": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -557,6 +968,20 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -594,6 +1019,14 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -612,6 +1045,50 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/rsbuild-plugin-dts": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.2.2.tgz", @@ -639,12 +1116,104 @@ } } }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", "dev": true }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -724,6 +1293,28 @@ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -732,6 +1323,14 @@ "engines": { "node": ">= 8" } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true, + "peer": true } } } diff --git a/package.json b/package.json index 209b7e4..3a3e23e 100644 --- a/package.json +++ b/package.json @@ -1,42 +1,31 @@ { "name": "@nsnanocat/util", "description": "Pure JS's util module for well-known iOS network tools", - "type": "module", "author": "VirgilClyne ", "homepage": "https://NSNanoCat.github.io/util", - "keywords": [ - "loon", - "quantumult", - "surge", - "shadowrocket", - "stash", - "egern" - ], + "keywords": ["loon", "quantumult", "surge", "shadowrocket", "stash", "egern"], "license": "Apache-2.0", "bugs": "https://github.com/NSNanoCat/util/issues", - "main": "./dist/index.cjs", - "module": "./dist/index.js", + "main": "./dist/index.js", + "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" + "import": "./dist/index.mjs", + "require": "./dist/index.js" }, "./getStorage": { "types": "./dist/getStorage.d.ts", - "import": "./dist/getStorage.js", - "require": "./dist/getStorage.cjs" + "import": "./dist/getStorage.mjs" }, "./polyfill/**": { "types": "./dist/polyfill/**.d.ts", - "import": "./dist/polyfill/**.js", - "require": "./dist/polyfill/**.cjs" + "import": "./dist/polyfill/**.mjs" }, "./lib/**": { "types": "./dist/lib/**.d.ts", - "import": "./dist/lib/**.js", - "require": "./dist/lib/**.cjs" + "import": "./dist/lib/**.mjs" } }, "scripts": { @@ -50,9 +39,7 @@ "type": "git", "url": "https://github.com/NSNanoCat/util.git" }, - "files": [ - "dist" - ], + "files": ["dist"], "dependencies": { "type-fest": "^4.31.0" }, diff --git a/rslib.config.ts b/rslib.config.ts index 855b881..3de4a5c 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -1,13 +1,55 @@ import { defineConfig } from '@rslib/core'; +import path from 'node:path'; +import fs from 'node:fs'; +import { wait } from './src/lib/wait'; export default defineConfig({ lib: [ { format: 'esm', syntax: 'es2021', bundle: false, dts: true }, - { format: 'cjs', syntax: 'es2021', bundle: false }, + // { format: 'cjs', syntax: 'es2021', bundle: false }, ], source: { entry: { - index: './src/**', + index: ['./src/**', '!./src/**/*.d.ts', '!./src/**/*.mjs'], }, }, + output: { + copy: [ + { + from: 'polyfill/*.mjs', + context: path.join(__dirname, 'src'), + }, + { + from: './src/polyfill/*.d.ts', + to: ({ context, absoluteFilename }) => + path + .relative(context, absoluteFilename || '') + .replace(/^src\//, '') + .replace(/\.d\.ts$/, '.d.ts.temp'), + }, + ], + }, + plugins: [ + { + name: 'organize', + setup: (api) => { + api.onAfterBuild(async () => { + await wait(1000); + const distPath = path.join(__dirname, 'dist'); + await fs.promises.copyFile(path.join(distPath, 'index.mjs'), path.join(distPath, 'index.js')); + const tempFileReg = /\.temp$/; + fs.promises.readdir(path.join(distPath, 'polyfill')).then((files) => { + files.forEach((file) => { + if (tempFileReg.test(file)) { + fs.renameSync( + path.join(distPath, 'polyfill', file), + path.join(distPath, 'polyfill', file.replace(tempFileReg, '')), + ); + } + }); + }); + }); + }, + }, + ], }); diff --git a/src/lib/app.ts b/src/lib/app.ts index a888f9a..dfb2c88 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -1,28 +1,29 @@ /** * Current app name */ -export const $app: "Quantumult X" | "Loon" | "Shadowrocket" | "Egern" | "Surge" | "Stash" | "Node.js" | undefined = (() => { - if ('$task' in globalThis) { - return 'Quantumult X'; - } - if ('$loon' in globalThis) { - return 'Loon'; - } - if ('$rocket' in globalThis) { - return 'Shadowrocket'; - } - if ('Egern' in globalThis) { - return 'Egern'; - } - if ('$environment' in globalThis) { - if (globalThis.$environment['surge-version']) { - return 'Surge'; +export const $app: 'Quantumult X' | 'Loon' | 'Shadowrocket' | 'Egern' | 'Surge' | 'Stash' | 'Node.js' | undefined = + (() => { + if ('$task' in globalThis) { + return 'Quantumult X'; } - if (globalThis.$environment['stash-version']) { - return 'Stash'; + if ('$loon' in globalThis) { + return 'Loon'; } - } - if (typeof module !== 'undefined') { - return 'Node.js'; - } -})(); + if ('$rocket' in globalThis) { + return 'Shadowrocket'; + } + if ('Egern' in globalThis) { + return 'Egern'; + } + if ('$environment' in globalThis) { + if (globalThis.$environment['surge-version']) { + return 'Surge'; + } + if (globalThis.$environment['stash-version']) { + return 'Stash'; + } + } + if (typeof module !== 'undefined') { + return 'Node.js'; + } + })(); diff --git a/src/polyfill/Lodash.ts b/src/polyfill/Lodash.ts index d7fa37a..0ed2178 100644 --- a/src/polyfill/Lodash.ts +++ b/src/polyfill/Lodash.ts @@ -51,12 +51,15 @@ export const get = (obj: T, path: Path, defaultValue?: G export const set = (obj: T, path: Path, value: Get) => { const setPath = (Array.isArray(path) ? path : toPath(path)) as string[]; - setPath.slice(0, -1).reduce((prev, key, index) => { - if (typeof prev[key] !== 'object' || prev[key] === null) { - prev[key] = /^\d+$/.test(setPath[index + 1]) ? [] : {}; - } - return prev[key]; - }, obj as Record)[setPath[setPath.length - 1]] = value; + setPath.slice(0, -1).reduce( + (prev, key, index) => { + if (typeof prev[key] !== 'object' || prev[key] === null) { + prev[key] = /^\d+$/.test(setPath[index + 1]) ? [] : {}; + } + return prev[key]; + }, + obj as Record, + )[setPath[setPath.length - 1]] = value; return obj; }; @@ -70,7 +73,7 @@ export const unset = (obj: T, path: Path) => { } return Object(previousValue)[currentValue]; }, obj); -} +}; export const omit = & string>>(obj: T, paths: PathArray) => { const result = { ...obj }; @@ -86,9 +89,9 @@ export const pick = & string (result as any)[key] = value; return result; }, - {} as PickDeep + {} as PickDeep, ); -} +}; export const Lodash = { escape, @@ -99,4 +102,4 @@ export const Lodash = { unset, omit, pick, -} \ No newline at end of file +}; diff --git a/src/polyfill/Storage.d.ts b/src/polyfill/Storage.d.ts new file mode 100644 index 0000000..c23efa1 --- /dev/null +++ b/src/polyfill/Storage.d.ts @@ -0,0 +1,8 @@ +export declare class Storage { + static data: Record; + static dataFile: string; + static getItem(keyName: string, defaultValue?: T): T; + static setItem(keyName: string, value: any): boolean; + static removeItem(keyName: string): boolean; + static clear(): boolean; +} diff --git a/src/polyfill/Storage.mjs b/src/polyfill/Storage.mjs new file mode 100644 index 0000000..98e5e17 --- /dev/null +++ b/src/polyfill/Storage.mjs @@ -0,0 +1,185 @@ +import { $app } from '../lib/app.mjs'; +import { Lodash as _ } from './Lodash.mjs'; +export class Storage { + static data = null; + static dataFile = 'box.dat'; + static #nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; + static getItem(keyName, defaultValue = null) { + let keyValue1 = defaultValue; + switch (keyName.startsWith('@')) { + case true: { + const { key, path } = keyName.match(Storage.#nameRegex)?.groups; + keyName = key; + let value = Storage.getItem(keyName, {}); + if ('object' != typeof value) value = {}; + keyValue1 = _.get(value, path); + try { + keyValue1 = JSON.parse(keyValue1); + } catch (e) {} + break; + } + default: + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + keyValue1 = $persistentStore.read(keyName); + break; + case 'Quantumult X': + keyValue1 = $prefs.valueForKey(keyName); + break; + case 'Node.js': + Storage.data = Storage.#loaddata(Storage.dataFile); + keyValue1 = Storage.data?.[keyName]; + break; + default: + keyValue1 = Storage.data?.[keyName] || null; + break; + } + try { + keyValue1 = JSON.parse(keyValue1); + } catch (e) {} + break; + } + return keyValue1 ?? defaultValue; + } + static setItem(keyName = new String(), keyValue1 = new String()) { + let result = false; + switch (typeof keyValue1) { + case 'object': + keyValue1 = JSON.stringify(keyValue1); + break; + default: + keyValue1 = String(keyValue1); + break; + } + switch (keyName.startsWith('@')) { + case true: { + const { key, path } = keyName.match(Storage.#nameRegex)?.groups; + keyName = key; + let value = Storage.getItem(keyName, {}); + if ('object' != typeof value) value = {}; + _.set(value, path, keyValue1); + result = Storage.setItem(keyName, value); + break; + } + default: + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + result = $persistentStore.write(keyValue1, keyName); + break; + case 'Quantumult X': + result = $prefs.setValueForKey(keyValue1, keyName); + break; + case 'Node.js': + Storage.data = Storage.#loaddata(Storage.dataFile); + Storage.data[keyName] = keyValue1; + Storage.#writedata(Storage.dataFile); + result = true; + break; + default: + result = Storage.data?.[keyName] || null; + break; + } + break; + } + return result; + } + static removeItem(keyName) { + let result = false; + switch (keyName.startsWith('@')) { + case true: { + const { key, path } = keyName.match(Storage.#nameRegex)?.groups; + keyName = key; + let value = Storage.getItem(keyName); + if ('object' != typeof value) value = {}; + keyValue = _.unset(value, path); + result = Storage.setItem(keyName, value); + break; + } + default: + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + result = false; + break; + case 'Quantumult X': + result = $prefs.removeValueForKey(keyName); + break; + case 'Node.js': + result = false; + break; + default: + result = false; + break; + } + break; + } + return result; + } + static clear() { + let result = false; + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + result = false; + break; + case 'Quantumult X': + result = $prefs.removeAllValues(); + break; + case 'Node.js': + result = false; + break; + default: + result = false; + break; + } + return result; + } + static #loaddata = (dataFile) => { + if ('Node.js' !== $app) return {}; + { + this.fs = this.fs ? this.fs : require('node:fs'); + this.path = this.path ? this.path : require('node:path'); + const curDirDataFilePath = this.path.resolve(dataFile); + const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); + const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); + const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); + if (!isCurDirDataFile && !isRootDirDataFile) return {}; + { + const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath; + try { + return JSON.parse(this.fs.readFileSync(datPath)); + } catch (e) { + return {}; + } + } + } + }; + static #writedata = (dataFile = this.dataFile) => { + if ('Node.js' === $app) { + this.fs = this.fs ? this.fs : require('node:fs'); + this.path = this.path ? this.path : require('node:path'); + const curDirDataFilePath = this.path.resolve(dataFile); + const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); + const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); + const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); + const jsondata = JSON.stringify(this.data); + if (isCurDirDataFile) this.fs.writeFileSync(curDirDataFilePath, jsondata); + else if (isRootDirDataFile) this.fs.writeFileSync(rootDirDataFilePath, jsondata); + else this.fs.writeFileSync(curDirDataFilePath, jsondata); + } + }; +} diff --git a/src/polyfill/Storage.ts b/src/polyfill/Storage.ts deleted file mode 100644 index c2d24fd..0000000 --- a/src/polyfill/Storage.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { get, set, unset } from './Lodash'; -import { $app } from '../lib/app'; - -declare const $persistentStore: { - read: (key: string) => string | null; - write: (value: string, key: string) => boolean; -}; - -declare const $prefs: { - valueForKey: (key: string) => string | null; - setValueForKey: (value: string, key: string) => boolean; - removeValueForKey: (key: string) => boolean; - removeAllValues: () => boolean; -}; - -interface StorageData { - [key: string]: any; -} - -export class StorageClass { - private data: StorageData | null = null; - private readonly dataFile: string = 'box.dat'; - private readonly nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; - - constructor() { - if ($app === 'Node.js') { - this.#loadData(this.dataFile).then((res) => { - this.data = res; - }) - } - } - - public getItem(keyName: string, defaultValue = null as T): T { - let keyValue = defaultValue; - - if (keyName.startsWith('@')) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key, {}); - if (typeof value !== 'object') { - value = {}; - } - keyValue = get(value, path); - try { - keyValue = JSON.parse(keyValue as string); - } catch { - // Ignore parse error - } - } - } else { - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - keyValue = $persistentStore.read(keyName) as T; - break; - case 'Quantumult X': - keyValue = $prefs.valueForKey(keyName) as T; - break; - case 'Node.js': - this.data = this.data || {}; - keyValue = this.data[keyName]; - break; - default: - keyValue = null as T; - break; - } - - try { - keyValue = JSON.parse(keyValue as string); - } catch { - // Ignore parse error - } - } - - return keyValue ?? defaultValue; - } - - public setItem(keyName: string, value: any): boolean { - let keyValue = value; - if (typeof keyValue === 'object') { - keyValue = JSON.stringify(keyValue); - } else { - keyValue = String(keyValue); - } - - if (keyName.startsWith('@')) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key, {}); - if (typeof value !== 'object') value = {}; - set(value, path, keyValue); - return this.setItem(keyName, value); - } - } else { - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - return $persistentStore.write(keyValue, keyName); - case 'Quantumult X': - return $prefs.setValueForKey(keyValue, keyName); - case 'Node.js': - this.data = this.data || {}; - this.data[keyName] = keyValue; - this.#writeData(this.dataFile); - return true; - default: - return false; - } - } - - return false; - } - - public removeItem(keyName: string): boolean { - if (keyName.startsWith('@')) { - const { key, path } = keyName.match(this.nameRegex)?.groups || {}; - if (key) { - let value = this.getItem(key); - if (typeof value !== 'object') value = {}; - unset(value, path); - return this.setItem(key, value); - } - } else { - switch ($app) { - case 'Quantumult X': - return $prefs.removeValueForKey(keyName); - default: - return false; - } - } - - return false; - } - - public clear(): boolean { - switch ($app) { - case 'Quantumult X': - return $prefs.removeAllValues(); - default: - return false; - } - } - - async #getNodeModule() { - if ($app === 'Node.js') { - // biome-ignore lint/style/useNodejsImportProtocol: - const fs = await import('fs') - // biome-ignore lint/style/useNodejsImportProtocol: - const path = await import('path') - return { fs, path } - } - return null; - } - - async #loadData(dataFile: string): Promise { - const { fs, path } = await this.#getNodeModule() ?? {}; - if (!fs || !path) { - return {}; - } - const curDirDataFilePath = path.resolve(dataFile); - const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); - if (fs.existsSync(curDirDataFilePath)) { - return JSON.parse(fs.readFileSync(curDirDataFilePath, 'utf-8')) || {}; - } - if (fs.existsSync(rootDirDataFilePath)) { - return JSON.parse(fs.readFileSync(rootDirDataFilePath, 'utf-8')) || {}; - } - return {}; - } - - async #writeData(dataFile: string): Promise { - const { fs, path } = await this.#getNodeModule() ?? {}; - if (!fs || !path) { - return - } - const dataFilePath = path.resolve(dataFile); - fs.writeFileSync(dataFilePath, JSON.stringify(this.data), 'utf-8'); - } -} - -// 导出初始化后的实例 -export const Storage = new StorageClass(); diff --git a/src/polyfill/fetch-node.d.ts b/src/polyfill/fetch-node.d.ts new file mode 100644 index 0000000..489a89b --- /dev/null +++ b/src/polyfill/fetch-node.d.ts @@ -0,0 +1 @@ +export const getNodeFetch: () => Promise<{ fetch: typeof import('node-fetch').default }>; diff --git a/src/polyfill/fetch-node.mjs b/src/polyfill/fetch-node.mjs new file mode 100644 index 0000000..e8c037a --- /dev/null +++ b/src/polyfill/fetch-node.mjs @@ -0,0 +1,8 @@ +export const getNodeFetch = () => { + const nodeFetch = globalThis.fetch ? globalThis.fetch : require('node-fetch'); + const fetchCookie = globalThis.fetchCookie ? globalThis.fetchCookie : require('fetch-cookie').default; + const fetch = fetchCookie(nodeFetch); + return { + fetch, + }; +}; diff --git a/src/polyfill/fetch.ts b/src/polyfill/fetch.ts index 86323c3..7ac317e 100644 --- a/src/polyfill/fetch.ts +++ b/src/polyfill/fetch.ts @@ -139,18 +139,14 @@ export async function fetch( } if ($app === 'Node.js') { - const nodeFetch = globalThis.fetch ? globalThis.fetch : await import('node-fetch').then((module) => module.default); - const fetchCookie = (globalThis as any).fetchCookie - ? (globalThis as any).fetchCookie - : await import('fetch-cookie').then((module) => module.default); - const fetch = fetchCookie(nodeFetch); + const fetch = await import('./fetch-node').then((module) => module.getNodeFetch().then((module) => module.fetch)); // 转换请求参数 params.timeout = (params.timeout ?? 5) * 1000; params.redirect = params.redirection ? 'follow' : 'manual'; const { url, ...options } = params; // 发送请求 return Promise.race([ - await fetch(url, options) + await fetch(url as string, options as any) .then(async (response: any) => { const bodyBytes = await response.arrayBuffer(); let headers: any; @@ -184,7 +180,7 @@ export async function fetch( reject(new Error(`${Function.name}: 请求超时, 请检查网络后重试`)); }, params.timeout); }), - ]); + ]) as unknown as FetchResponse; } if ($app === 'Loon') { From 4322154670402658438f0199cc6b0119c4e5ff69 Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:37:23 +0800 Subject: [PATCH 25/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E5=AF=B9=E6=8B=89=E5=8F=96=E8=AF=B7=E6=B1=82=E7=9A=84=E5=86=99?= =?UTF-8?q?=E5=85=A5=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index dc49b60..f3837ee 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -12,7 +12,7 @@ jobs: permissions: packages: write contents: read - issues: write + pull-requests: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From 657bea280792d78ee8ffef25cd3c1e8a5978dde8 Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:39:35 +0800 Subject: [PATCH 26/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BB=A5=E5=8C=85=E5=90=AB?= =?UTF-8?q?=20npm=20=E5=AE=89=E8=A3=85=E6=8C=87=E4=BB=A4=E5=92=8C=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index f3837ee..882a512 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -28,9 +28,8 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | VERSION=$(node -p "require('./package.json').version") - echo "npm version is: $VERSION" PR_NUMBER=${{ github.event.pull_request.number }} - COMMENT_BODY="The npm version is: $VERSION" + COMMENT_BODY="Preview version $VERSION published to npm. To install, run \`npm install @nsnanocat/util@$VERSION\`" gh pr comment $PR_NUMBER --body "$COMMENT_BODY" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 7a02d69737dcf6eaae45fad35fa2a011292dfaa8 Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:41:38 +0800 Subject: [PATCH 27/31] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E6=A0=BC=E5=BC=8F=E4=BB=A5=E6=AD=A3=E7=A1=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=89=88=E6=9C=AC=E4=BF=A1=E6=81=AF=E5=92=8C=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 882a512..5c08d1e 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -29,7 +29,7 @@ jobs: - run: | VERSION=$(node -p "require('./package.json').version") PR_NUMBER=${{ github.event.pull_request.number }} - COMMENT_BODY="Preview version $VERSION published to npm. To install, run \`npm install @nsnanocat/util@$VERSION\`" + COMMENT_BODY="Preview version \`$VERSION\`published to npm. To install, run \n\n\`\`\`bash\nnpm install @nsnanocat/util@$VERSION\`\`\`" gh pr comment $PR_NUMBER --body "$COMMENT_BODY" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 7ca448c341391d5be74c719adebb2e97a923d8a9 Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:42:33 +0800 Subject: [PATCH 28/31] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E6=A0=BC=E5=BC=8F=E4=BB=A5=E6=AD=A3=E7=A1=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=AE=89=E8=A3=85=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 5c08d1e..62fa584 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -29,7 +29,7 @@ jobs: - run: | VERSION=$(node -p "require('./package.json').version") PR_NUMBER=${{ github.event.pull_request.number }} - COMMENT_BODY="Preview version \`$VERSION\`published to npm. To install, run \n\n\`\`\`bash\nnpm install @nsnanocat/util@$VERSION\`\`\`" + COMMENT_BODY="Preview version \`$VERSION\`published to npm. To install, run \\n\\n\`\`\`bash\\nnpm install @nsnanocat/util@$VERSION\\n\`\`\`" gh pr comment $PR_NUMBER --body "$COMMENT_BODY" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From f0c4a213fb48bc7be439048f29d95e6905c54c7e Mon Sep 17 00:00:00 2001 From: baranwang Date: Sun, 5 Jan 2025 15:49:51 +0800 Subject: [PATCH 29/31] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E6=A0=BC=E5=BC=8F=E4=BB=A5=E6=AD=A3=E7=A1=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=AE=89=E8=A3=85=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 62fa584..931d447 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -29,7 +29,10 @@ jobs: - run: | VERSION=$(node -p "require('./package.json').version") PR_NUMBER=${{ github.event.pull_request.number }} - COMMENT_BODY="Preview version \`$VERSION\`published to npm. To install, run \\n\\n\`\`\`bash\\nnpm install @nsnanocat/util@$VERSION\\n\`\`\`" + COMMENT_BODY="Preview version \`$VERSION\` published to npm. To install, run: + \`\`\`bash + npm install @nsnanocat/util@$VERSION + \`\`\`" gh pr comment $PR_NUMBER --body "$COMMENT_BODY" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 496502c7a49c25e5845a59b1d5111457215f28fc Mon Sep 17 00:00:00 2001 From: baranwang Date: Sat, 11 Jan 2025 12:35:09 +0800 Subject: [PATCH 30/31] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20package.json?= =?UTF-8?q?=20=E4=B8=AD=E7=9A=84=E6=A8=A1=E5=9D=97=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B9=B6=E6=9B=B4=E6=96=B0=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BB=A5=E9=87=8D=E5=91=BD=E5=90=8D=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 20 -------------------- rslib.config.ts | 3 +-- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/package.json b/package.json index 3a3e23e..a0e9b80 100644 --- a/package.json +++ b/package.json @@ -7,27 +7,7 @@ "license": "Apache-2.0", "bugs": "https://github.com/NSNanoCat/util/issues", "main": "./dist/index.js", - "module": "./dist/index.mjs", "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.js" - }, - "./getStorage": { - "types": "./dist/getStorage.d.ts", - "import": "./dist/getStorage.mjs" - }, - "./polyfill/**": { - "types": "./dist/polyfill/**.d.ts", - "import": "./dist/polyfill/**.mjs" - }, - "./lib/**": { - "types": "./dist/lib/**.d.ts", - "import": "./dist/lib/**.mjs" - } - }, "scripts": { "build": "rslib build", "check": "biome check --write", diff --git a/rslib.config.ts b/rslib.config.ts index 3de4a5c..550aeb6 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -6,7 +6,6 @@ import { wait } from './src/lib/wait'; export default defineConfig({ lib: [ { format: 'esm', syntax: 'es2021', bundle: false, dts: true }, - // { format: 'cjs', syntax: 'es2021', bundle: false }, ], source: { entry: { @@ -36,7 +35,7 @@ export default defineConfig({ api.onAfterBuild(async () => { await wait(1000); const distPath = path.join(__dirname, 'dist'); - await fs.promises.copyFile(path.join(distPath, 'index.mjs'), path.join(distPath, 'index.js')); + await fs.promises.rename(path.join(distPath, 'index.mjs'), path.join(distPath, 'index.js')); const tempFileReg = /\.temp$/; fs.promises.readdir(path.join(distPath, 'polyfill')).then((files) => { files.forEach((file) => { From 3ebfb78aea9a46a0dba51628a7a31ed8645c60a4 Mon Sep 17 00:00:00 2001 From: baranwang Date: Sat, 11 Jan 2025 13:17:20 +0800 Subject: [PATCH 31/31] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E5=92=8C=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E9=87=8D=E6=9E=84=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 1209 +++++------------ package.json | 19 +- rslib.config.ts | 54 - src/{getStorage.ts => getStorage.mts} | 4 +- src/index.ts | 14 +- src/lib/{app.ts => app.mts} | 0 src/lib/{done.ts => done.mts} | 8 +- src/lib/{environment.ts => environment.mts} | 2 +- src/lib/index.mts | 5 + src/lib/index.ts | 5 - src/lib/{notification.ts => notification.mts} | 4 +- src/lib/{runScript.ts => runScript.mts} | 6 +- src/lib/{time.ts => time.mts} | 0 src/lib/{wait.ts => wait.mts} | 0 src/polyfill/{Console.ts => Console.mts} | 2 +- src/polyfill/{Lodash.ts => Lodash.mts} | 0 .../{StatusTexts.ts => StatusTexts.mts} | 0 src/polyfill/Storage.d.ts | 8 - src/polyfill/Storage.mjs | 185 --- src/polyfill/Storage.mts | 186 +++ src/polyfill/fetch-node.d.ts | 1 - .../{fetch-node.mjs => fetch-node.mts} | 2 +- src/polyfill/{fetch.ts => fetch.mts} | 8 +- src/polyfill/index.mts | 5 + src/polyfill/index.ts | 5 - tsconfig.json | 7 +- 26 files changed, 593 insertions(+), 1146 deletions(-) delete mode 100644 rslib.config.ts rename src/{getStorage.ts => getStorage.mts} (97%) rename src/lib/{app.ts => app.mts} (100%) rename src/lib/{done.ts => done.mts} (93%) rename src/lib/{environment.ts => environment.mts} (96%) create mode 100644 src/lib/index.mts delete mode 100644 src/lib/index.ts rename src/lib/{notification.ts => notification.mts} (98%) rename src/lib/{runScript.ts => runScript.mts} (90%) rename src/lib/{time.ts => time.mts} (100%) rename src/lib/{wait.ts => wait.mts} (100%) rename src/polyfill/{Console.ts => Console.mts} (99%) rename src/polyfill/{Lodash.ts => Lodash.mts} (100%) rename src/polyfill/{StatusTexts.ts => StatusTexts.mts} (100%) delete mode 100644 src/polyfill/Storage.d.ts delete mode 100644 src/polyfill/Storage.mjs create mode 100644 src/polyfill/Storage.mts delete mode 100644 src/polyfill/fetch-node.d.ts rename src/polyfill/{fetch-node.mjs => fetch-node.mts} (60%) rename src/polyfill/{fetch.ts => fetch.mts} (96%) create mode 100644 src/polyfill/index.mts delete mode 100644 src/polyfill/index.ts diff --git a/package-lock.json b/package-lock.json index 2262765..ac9cbba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,10 @@ }, "devDependencies": { "@biomejs/biome": "^1.9.2", - "@rslib/core": "^0.2.2", "@types/node": "^22.10.2", "fetch-cookie": "^3.1.0", "node-fetch": "^3.3.2", + "rimraf": "^6.0.1", "typescript": "^5.6.3" }, "optionalDependencies": { @@ -177,443 +177,23 @@ "node": ">=14.21.3" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@microsoft/api-extractor": { - "version": "7.48.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.1.tgz", - "integrity": "sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@microsoft/api-extractor-model": "7.30.1", - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.1", - "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.14.4", - "@rushstack/ts-command-line": "4.23.2", - "lodash": "~4.17.15", - "minimatch": "~3.0.3", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "source-map": "~0.6.1", - "typescript": "5.4.2" - }, - "bin": { - "api-extractor": "bin/api-extractor" - } - }, - "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.1.tgz", - "integrity": "sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.1" - } - }, - "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@microsoft/tsdoc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", - "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@microsoft/tsdoc-config": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", - "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@microsoft/tsdoc": "0.15.1", - "ajv": "~8.12.0", - "jju": "~1.4.0", - "resolve": "~1.22.2" - } - }, - "node_modules/@module-federation/runtime": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", - "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", - "dev": true, - "dependencies": { - "@module-federation/sdk": "0.5.1" - } - }, - "node_modules/@module-federation/runtime-tools": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", - "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", - "dev": true, - "dependencies": { - "@module-federation/runtime": "0.5.1", - "@module-federation/webpack-bundler-runtime": "0.5.1" - } - }, - "node_modules/@module-federation/sdk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", - "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", - "dev": true - }, - "node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", - "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", - "dev": true, - "dependencies": { - "@module-federation/runtime": "0.5.1", - "@module-federation/sdk": "0.5.1" - } - }, - "node_modules/@rsbuild/core": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.1.13.tgz", - "integrity": "sha512-XBL2hrin8731W6iTGGL+x3cv07n4vm2D7u6XHRwtQkRfySzAqGx7ThlQLdNX/dJwfsoQrYQuWl/qzaljjXtGtg==", - "dev": true, - "dependencies": { - "@rspack/core": "1.1.8", - "@rspack/lite-tapable": "~1.0.1", - "@swc/helpers": "^0.5.15", - "core-js": "~3.39.0" - }, - "bin": { - "rsbuild": "bin/rsbuild.js" - }, - "engines": { - "node": ">=16.7.0" - } - }, - "node_modules/@rslib/core": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@rslib/core/-/core-0.2.2.tgz", - "integrity": "sha512-u4qKfoO2YAdtoga6NqCDcTfvqyaTZj/L0kZjDrbThMcD51qUb8HiCS8pX5Hwj5v4doGkk+rHeQnw0Ad7HyMPMQ==", - "dev": true, - "dependencies": { - "@rsbuild/core": "~1.1.13", - "rsbuild-plugin-dts": "0.2.2", - "tinyglobby": "^0.2.10" - }, - "bin": { - "rslib": "bin/rslib.js" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@microsoft/api-extractor": "^7", - "typescript": "^5" - }, - "peerDependenciesMeta": { - "@microsoft/api-extractor": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/@rspack/binding": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.8.tgz", - "integrity": "sha512-+/JzXx1HctfgPj+XtsCTbRkxiaOfAXGZZLEvs7jgp04WgWRSZ5u97WRCePNPvy+sCfOEH/2zw2ZK36Z7oQRGhQ==", - "dev": true, - "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.1.8", - "@rspack/binding-darwin-x64": "1.1.8", - "@rspack/binding-linux-arm64-gnu": "1.1.8", - "@rspack/binding-linux-arm64-musl": "1.1.8", - "@rspack/binding-linux-x64-gnu": "1.1.8", - "@rspack/binding-linux-x64-musl": "1.1.8", - "@rspack/binding-win32-arm64-msvc": "1.1.8", - "@rspack/binding-win32-ia32-msvc": "1.1.8", - "@rspack/binding-win32-x64-msvc": "1.1.8" - } - }, - "node_modules/@rspack/binding-darwin-arm64": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.8.tgz", - "integrity": "sha512-I7avr471ghQ3LAqKm2fuXuJPLgQ9gffn5Q4nHi8rsukuZUtiLDPfYzK1QuupEp2JXRWM1gG5lIbSUOht3cD6Ug==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rspack/binding-darwin-x64": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.8.tgz", - "integrity": "sha512-vfqf/c+mcx8rr1M8LnqKmzDdnrgguflZnjGerBLjNerAc+dcUp3lCvNxRIvZ2TkSZZBW8BpCMgjj3n70CZ4VLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rspack/binding-linux-arm64-gnu": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.8.tgz", - "integrity": "sha512-lZlO/rAJSeozi+qtVLkGSXfe+riPawCwM4FsrflELfNlvvEXpANwtrdJ+LsaNVXcgvhh50ZX2KicTdmx9G2b6Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-arm64-musl": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.8.tgz", - "integrity": "sha512-bX7exULSZwy8xtDh6Z65b6sRC4uSxGuyvSLCEKyhmG6AnJkg0gQMxk3hoO0hWnyGEZgdJEn+jEhk0fjl+6ZRAQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-x64-gnu": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.8.tgz", - "integrity": "sha512-2Prw2USgTJ3aLdLExfik8pAwAHbX4MZrACBGEmR7Vbb56kLjC+++fXkciRc50pUDK4JFr1VQ7eNZrJuDR6GG6Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-linux-x64-musl": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.8.tgz", - "integrity": "sha512-bnVGB/mQBKEdzOU/CPmcOE3qEXxGOGGW7/i6iLl2MamVOykJq8fYjL9j86yi6L0r009ja16OgWckykQGc4UqGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rspack/binding-win32-arm64-msvc": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.8.tgz", - "integrity": "sha512-u+na3gxhzeksm4xZyAzn1+XWo5a5j7hgWA/KcFPDQ8qQNkRknx4jnQMxVtcZ9pLskAYV4AcOV/AIximx7zvv8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/binding-win32-ia32-msvc": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.8.tgz", - "integrity": "sha512-FijUxym1INd5fFHwVCLuVP8XEAb4Sk1sMwEEQUlugiDra9ZsLaPw4OgPGxbxkD6SB0DeUz9Zq46Xbcf6d3OgfA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/binding-win32-x64-msvc": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.8.tgz", - "integrity": "sha512-SBzIcND4qpDt71jlu1MCDxt335tqInT3YID9V4DoQ4t8wgM/uad7EgKOWKTK6vc2RRaOIShfS2XzqjNUxPXh4w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rspack/core": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.8.tgz", - "integrity": "sha512-pcZtcj5iXLCuw9oElTYC47bp/RQADm/MMEb3djHdwJuSlFWfWPQi5QFgJ/lJAxIW9UNHnTFrYtytycfjpuoEcA==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "dependencies": { - "@module-federation/runtime-tools": "0.5.1", - "@rspack/binding": "1.1.8", - "@rspack/lite-tapable": "1.0.1", - "caniuse-lite": "^1.0.30001616" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.1" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@rspack/lite-tapable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", - "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@rushstack/node-core-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", - "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ajv": "~8.13.0", - "ajv-draft-04": "~1.0.0", - "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/node-core-library/node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@rushstack/rig-package": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", - "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "resolve": "~1.22.1", - "strip-json-comments": "~3.1.1" - } - }, - "node_modules/@rushstack/terminal": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.4.tgz", - "integrity": "sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@rushstack/node-core-library": "5.10.1", - "supports-color": "~8.1.1" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/ts-command-line": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.2.tgz", - "integrity": "sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@rushstack/terminal": "0.14.4", - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "string-argv": "~0.3.1" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "dev": true, - "dependencies": { - "tslib": "^2.8.0" + "node": ">=12" } }, - "node_modules/@types/argparse": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -623,127 +203,66 @@ "undici-types": "~6.20.0" } }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "optional": true, - "peer": true, - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001690", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", - "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "optional": true, - "peer": true + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/core-js": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", - "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, "node_modules/data-uri-to-buffer": { @@ -755,27 +274,17 @@ "node": ">= 12" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "optional": true, - "peer": true + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, - "node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/fetch-blob": { "version": "3.2.0", @@ -810,6 +319,22 @@ "tough-cookie": "^5.0.0" } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -822,164 +347,90 @@ "node": ">=12.20.0" } }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "node_modules/glob": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "optional": true, - "peer": true, + "node": "20 || >=22" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "balanced-match": "^1.0.0" } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "optional": true, - "peer": true, "dependencies": { - "hasown": "^2.0.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "optional": true, - "peer": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optional": true, - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=8" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "optional": true, - "peer": true + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "yallist": "^4.0.0" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=10" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" } }, "node_modules/node-domexception": { @@ -1019,118 +470,63 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "optional": true, - "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">= 0.4" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rsbuild-plugin-dts": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.2.2.tgz", - "integrity": "sha512-RwkVcMwig1+UHkVJFaD6tagjxZOQqIenbkLS+J85bEdKO/ra+YiLC1Gq3DItEv/hU02u5WPgJmQhaQWKb17T9w==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "dev": true, - "dependencies": { - "magic-string": "^0.30.17", - "picocolors": "1.1.1", - "tinyglobby": "^0.2.10" - }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@microsoft/api-extractor": "^7", - "@rsbuild/core": "1.x", - "typescript": "^5" - }, - "peerDependenciesMeta": { - "@microsoft/api-extractor": { - "optional": true - }, - "typescript": { - "optional": true - } + "node": "20 || >=22" } }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "lru-cache": "^6.0.0" + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" }, "bin": { - "semver": "bin/semver.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=10" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/set-cookie-parser": { @@ -1139,92 +535,133 @@ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", "dev": true }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "optional": true, - "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "optional": true, - "peer": true + "engines": { + "node": ">=8" + } }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "optional": true, - "peer": true, "engines": { - "node": ">=0.6.19" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "optional": true, - "peer": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "has-flag": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "optional": true, - "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/tinyglobby": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", - "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "fdir": "^6.4.2", - "picomatch": "^4.0.2" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/tldts": { @@ -1257,12 +694,6 @@ "node": ">=16" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, "node_modules/type-fest": { "version": "4.31.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.31.0.tgz", @@ -1293,44 +724,120 @@ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, - "optional": true, - "peer": true, "engines": { - "node": ">= 4.0.0" + "node": ">= 8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "optional": true, - "peer": true, "dependencies": { - "punycode": "^2.1.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "optional": true, - "peer": true + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } } } } diff --git a/package.json b/package.json index a0e9b80..1f90887 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,22 @@ "description": "Pure JS's util module for well-known iOS network tools", "author": "VirgilClyne ", "homepage": "https://NSNanoCat.github.io/util", - "keywords": ["loon", "quantumult", "surge", "shadowrocket", "stash", "egern"], + "keywords": [ + "loon", + "quantumult", + "surge", + "shadowrocket", + "stash", + "egern" + ], "license": "Apache-2.0", "bugs": "https://github.com/NSNanoCat/util/issues", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { - "build": "rslib build", + "prebuild": "rimraf dist", + "build": "tsc", "check": "biome check --write", - "dev": "rslib build --watch", "format": "biome format --write", "prepublishOnly": "npm run build" }, @@ -19,16 +26,18 @@ "type": "git", "url": "https://github.com/NSNanoCat/util.git" }, - "files": ["dist"], + "files": [ + "dist" + ], "dependencies": { "type-fest": "^4.31.0" }, "devDependencies": { "@biomejs/biome": "^1.9.2", - "@rslib/core": "^0.2.2", "@types/node": "^22.10.2", "fetch-cookie": "^3.1.0", "node-fetch": "^3.3.2", + "rimraf": "^6.0.1", "typescript": "^5.6.3" }, "optionalDependencies": { diff --git a/rslib.config.ts b/rslib.config.ts deleted file mode 100644 index 550aeb6..0000000 --- a/rslib.config.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { defineConfig } from '@rslib/core'; -import path from 'node:path'; -import fs from 'node:fs'; -import { wait } from './src/lib/wait'; - -export default defineConfig({ - lib: [ - { format: 'esm', syntax: 'es2021', bundle: false, dts: true }, - ], - source: { - entry: { - index: ['./src/**', '!./src/**/*.d.ts', '!./src/**/*.mjs'], - }, - }, - output: { - copy: [ - { - from: 'polyfill/*.mjs', - context: path.join(__dirname, 'src'), - }, - { - from: './src/polyfill/*.d.ts', - to: ({ context, absoluteFilename }) => - path - .relative(context, absoluteFilename || '') - .replace(/^src\//, '') - .replace(/\.d\.ts$/, '.d.ts.temp'), - }, - ], - }, - plugins: [ - { - name: 'organize', - setup: (api) => { - api.onAfterBuild(async () => { - await wait(1000); - const distPath = path.join(__dirname, 'dist'); - await fs.promises.rename(path.join(distPath, 'index.mjs'), path.join(distPath, 'index.js')); - const tempFileReg = /\.temp$/; - fs.promises.readdir(path.join(distPath, 'polyfill')).then((files) => { - files.forEach((file) => { - if (tempFileReg.test(file)) { - fs.renameSync( - path.join(distPath, 'polyfill', file), - path.join(distPath, 'polyfill', file.replace(tempFileReg, '')), - ); - } - }); - }); - }); - }, - }, - ], -}); diff --git a/src/getStorage.ts b/src/getStorage.mts similarity index 97% rename from src/getStorage.ts rename to src/getStorage.mts index 3b00e5a..d754872 100644 --- a/src/getStorage.ts +++ b/src/getStorage.mts @@ -1,5 +1,5 @@ -import { set } from './polyfill/Lodash'; -import { Storage } from './polyfill/Storage'; +import { set } from './polyfill/Lodash.mjs'; +import { Storage } from './polyfill/Storage.mjs'; type Database = Record; diff --git a/src/index.ts b/src/index.ts index 268b834..92bb0fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,3 @@ -export * from './lib/app'; -export * from './lib/done'; -export * from './lib/notification'; -export * from './lib/time'; -export * from './lib/wait'; -export * from './polyfill/Console'; -export * from './polyfill/fetch'; -export * from './polyfill/Lodash'; -export * from './polyfill/StatusTexts'; -export * from './polyfill/Storage'; -export * from './getStorage'; +export * from './lib/index.mjs'; +export * from './polyfill/index.mjs'; +export * from './getStorage.mjs'; diff --git a/src/lib/app.ts b/src/lib/app.mts similarity index 100% rename from src/lib/app.ts rename to src/lib/app.mts diff --git a/src/lib/done.ts b/src/lib/done.mts similarity index 93% rename from src/lib/done.ts rename to src/lib/done.mts index 8e2449c..985e9e4 100644 --- a/src/lib/done.ts +++ b/src/lib/done.mts @@ -1,7 +1,7 @@ -import { pick, set } from '../polyfill/Lodash'; -import { Console } from '../polyfill/Console'; -import { StatusTexts } from '../polyfill/StatusTexts'; -import { $app } from './app'; +import { pick, set } from '../polyfill/Lodash.mjs'; +import { Console } from '../polyfill/Console.mjs'; +import { StatusTexts } from '../polyfill/StatusTexts.mjs'; +import { $app } from './app.mjs'; interface DoneObject { status?: number | string; diff --git a/src/lib/environment.ts b/src/lib/environment.mts similarity index 96% rename from src/lib/environment.ts rename to src/lib/environment.mts index cc01b69..80323aa 100644 --- a/src/lib/environment.ts +++ b/src/lib/environment.mts @@ -1,4 +1,4 @@ -import { $app } from './app'; +import { $app } from './app.mjs'; interface Environment extends globalThis.Environment { app?: string; diff --git a/src/lib/index.mts b/src/lib/index.mts new file mode 100644 index 0000000..3618c51 --- /dev/null +++ b/src/lib/index.mts @@ -0,0 +1,5 @@ +export * from './app.mjs'; +export * from './done.mjs'; +export * from './notification.mjs'; +export * from './time.mjs'; +export * from './wait.mjs'; diff --git a/src/lib/index.ts b/src/lib/index.ts deleted file mode 100644 index 9ad1827..0000000 --- a/src/lib/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './app'; -export * from './done'; -export * from './notification'; -export * from './time'; -export * from './wait'; diff --git a/src/lib/notification.ts b/src/lib/notification.mts similarity index 98% rename from src/lib/notification.ts rename to src/lib/notification.mts index a14ba6b..2511ca8 100644 --- a/src/lib/notification.ts +++ b/src/lib/notification.mts @@ -1,5 +1,5 @@ -import { Console } from '../polyfill/Console.js'; -import { $app } from './app.js'; +import { Console } from '../polyfill/Console.mjs'; +import { $app } from './app.mjs'; interface NotificationContent { open?: string; diff --git a/src/lib/runScript.ts b/src/lib/runScript.mts similarity index 90% rename from src/lib/runScript.ts rename to src/lib/runScript.mts index 7cc5222..9b6f16e 100644 --- a/src/lib/runScript.ts +++ b/src/lib/runScript.mts @@ -1,6 +1,6 @@ -import { Console } from '../polyfill/Console'; -import { Storage } from '../polyfill/Storage'; -import { fetch } from '../polyfill/fetch'; +import { Console } from '../polyfill/Console.mjs'; +import { Storage } from '../polyfill/Storage.mjs'; +import { fetch } from '../polyfill/fetch.mjs'; export async function runScript(script: string, runOpts: { timeout?: number } = {}) { try { diff --git a/src/lib/time.ts b/src/lib/time.mts similarity index 100% rename from src/lib/time.ts rename to src/lib/time.mts diff --git a/src/lib/wait.ts b/src/lib/wait.mts similarity index 100% rename from src/lib/wait.ts rename to src/lib/wait.mts diff --git a/src/polyfill/Console.ts b/src/polyfill/Console.mts similarity index 99% rename from src/polyfill/Console.ts rename to src/polyfill/Console.mts index e93856b..cd44110 100644 --- a/src/polyfill/Console.ts +++ b/src/polyfill/Console.mts @@ -1,4 +1,4 @@ -import { $app } from '../lib/app'; +import { $app } from '../lib/app.mjs'; class ConsoleFactory { #counts = new Map([]); diff --git a/src/polyfill/Lodash.ts b/src/polyfill/Lodash.mts similarity index 100% rename from src/polyfill/Lodash.ts rename to src/polyfill/Lodash.mts diff --git a/src/polyfill/StatusTexts.ts b/src/polyfill/StatusTexts.mts similarity index 100% rename from src/polyfill/StatusTexts.ts rename to src/polyfill/StatusTexts.mts diff --git a/src/polyfill/Storage.d.ts b/src/polyfill/Storage.d.ts deleted file mode 100644 index c23efa1..0000000 --- a/src/polyfill/Storage.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export declare class Storage { - static data: Record; - static dataFile: string; - static getItem(keyName: string, defaultValue?: T): T; - static setItem(keyName: string, value: any): boolean; - static removeItem(keyName: string): boolean; - static clear(): boolean; -} diff --git a/src/polyfill/Storage.mjs b/src/polyfill/Storage.mjs deleted file mode 100644 index 98e5e17..0000000 --- a/src/polyfill/Storage.mjs +++ /dev/null @@ -1,185 +0,0 @@ -import { $app } from '../lib/app.mjs'; -import { Lodash as _ } from './Lodash.mjs'; -export class Storage { - static data = null; - static dataFile = 'box.dat'; - static #nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; - static getItem(keyName, defaultValue = null) { - let keyValue1 = defaultValue; - switch (keyName.startsWith('@')) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName, {}); - if ('object' != typeof value) value = {}; - keyValue1 = _.get(value, path); - try { - keyValue1 = JSON.parse(keyValue1); - } catch (e) {} - break; - } - default: - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - keyValue1 = $persistentStore.read(keyName); - break; - case 'Quantumult X': - keyValue1 = $prefs.valueForKey(keyName); - break; - case 'Node.js': - Storage.data = Storage.#loaddata(Storage.dataFile); - keyValue1 = Storage.data?.[keyName]; - break; - default: - keyValue1 = Storage.data?.[keyName] || null; - break; - } - try { - keyValue1 = JSON.parse(keyValue1); - } catch (e) {} - break; - } - return keyValue1 ?? defaultValue; - } - static setItem(keyName = new String(), keyValue1 = new String()) { - let result = false; - switch (typeof keyValue1) { - case 'object': - keyValue1 = JSON.stringify(keyValue1); - break; - default: - keyValue1 = String(keyValue1); - break; - } - switch (keyName.startsWith('@')) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName, {}); - if ('object' != typeof value) value = {}; - _.set(value, path, keyValue1); - result = Storage.setItem(keyName, value); - break; - } - default: - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - result = $persistentStore.write(keyValue1, keyName); - break; - case 'Quantumult X': - result = $prefs.setValueForKey(keyValue1, keyName); - break; - case 'Node.js': - Storage.data = Storage.#loaddata(Storage.dataFile); - Storage.data[keyName] = keyValue1; - Storage.#writedata(Storage.dataFile); - result = true; - break; - default: - result = Storage.data?.[keyName] || null; - break; - } - break; - } - return result; - } - static removeItem(keyName) { - let result = false; - switch (keyName.startsWith('@')) { - case true: { - const { key, path } = keyName.match(Storage.#nameRegex)?.groups; - keyName = key; - let value = Storage.getItem(keyName); - if ('object' != typeof value) value = {}; - keyValue = _.unset(value, path); - result = Storage.setItem(keyName, value); - break; - } - default: - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - result = false; - break; - case 'Quantumult X': - result = $prefs.removeValueForKey(keyName); - break; - case 'Node.js': - result = false; - break; - default: - result = false; - break; - } - break; - } - return result; - } - static clear() { - let result = false; - switch ($app) { - case 'Surge': - case 'Loon': - case 'Stash': - case 'Egern': - case 'Shadowrocket': - result = false; - break; - case 'Quantumult X': - result = $prefs.removeAllValues(); - break; - case 'Node.js': - result = false; - break; - default: - result = false; - break; - } - return result; - } - static #loaddata = (dataFile) => { - if ('Node.js' !== $app) return {}; - { - this.fs = this.fs ? this.fs : require('node:fs'); - this.path = this.path ? this.path : require('node:path'); - const curDirDataFilePath = this.path.resolve(dataFile); - const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); - const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); - const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); - if (!isCurDirDataFile && !isRootDirDataFile) return {}; - { - const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath; - try { - return JSON.parse(this.fs.readFileSync(datPath)); - } catch (e) { - return {}; - } - } - } - }; - static #writedata = (dataFile = this.dataFile) => { - if ('Node.js' === $app) { - this.fs = this.fs ? this.fs : require('node:fs'); - this.path = this.path ? this.path : require('node:path'); - const curDirDataFilePath = this.path.resolve(dataFile); - const rootDirDataFilePath = this.path.resolve(process.cwd(), dataFile); - const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath); - const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath); - const jsondata = JSON.stringify(this.data); - if (isCurDirDataFile) this.fs.writeFileSync(curDirDataFilePath, jsondata); - else if (isRootDirDataFile) this.fs.writeFileSync(rootDirDataFilePath, jsondata); - else this.fs.writeFileSync(curDirDataFilePath, jsondata); - } - }; -} diff --git a/src/polyfill/Storage.mts b/src/polyfill/Storage.mts new file mode 100644 index 0000000..e0ff44c --- /dev/null +++ b/src/polyfill/Storage.mts @@ -0,0 +1,186 @@ +import { get, set, unset } from './Lodash.mjs'; +import { $app } from '../lib/app.mjs'; + +declare const $persistentStore: { + read: (key: string) => string | null; + write: (value: string, key: string) => boolean; +}; + +declare const $prefs: { + valueForKey: (key: string) => string | null; + setValueForKey: (value: string, key: string) => boolean; + removeValueForKey: (key: string) => boolean; + removeAllValues: () => boolean; +}; + +interface StorageData { + [key: string]: any; +} + +export class StorageClass { + private data: StorageData | null = null; + private readonly dataFile: string = 'box.dat'; + private readonly nameRegex = /^@(?[^.]+)(?:\.(?.*))?$/; + + constructor() { + if ($app === 'Node.js') { + this.data = this.#loadData(this.dataFile) + } + } + + public getItem(keyName: string, defaultValue = null as T): T { + let keyValue = defaultValue; + + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== 'object') { + value = {}; + } + keyValue = get(value, path); + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + } else { + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + keyValue = $persistentStore.read(keyName) as T; + break; + case 'Quantumult X': + keyValue = $prefs.valueForKey(keyName) as T; + break; + case 'Node.js': + this.data = this.data || {}; + keyValue = this.data[keyName]; + break; + default: + keyValue = null as T; + break; + } + + try { + keyValue = JSON.parse(keyValue as string); + } catch { + // Ignore parse error + } + } + + return keyValue ?? defaultValue; + } + + public setItem(keyName: string, value: any): boolean { + let keyValue = value; + if (typeof keyValue === 'object') { + keyValue = JSON.stringify(keyValue); + } else { + keyValue = String(keyValue); + } + + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key, {}); + if (typeof value !== 'object') value = {}; + set(value, path, keyValue); + return this.setItem(keyName, value); + } + } else { + switch ($app) { + case 'Surge': + case 'Loon': + case 'Stash': + case 'Egern': + case 'Shadowrocket': + return $persistentStore.write(keyValue, keyName); + case 'Quantumult X': + return $prefs.setValueForKey(keyValue, keyName); + case 'Node.js': + this.data = this.data || {}; + this.data[keyName] = keyValue; + this.#writeData(this.dataFile); + return true; + default: + return false; + } + } + + return false; + } + + public removeItem(keyName: string): boolean { + if (keyName.startsWith('@')) { + const { key, path } = keyName.match(this.nameRegex)?.groups || {}; + if (key) { + let value = this.getItem(key); + if (typeof value !== 'object') value = {}; + unset(value, path); + return this.setItem(key, value); + } + } else { + switch ($app) { + case 'Quantumult X': + return $prefs.removeValueForKey(keyName); + default: + return false; + } + } + + return false; + } + + public clear(): boolean { + switch ($app) { + case 'Quantumult X': + return $prefs.removeAllValues(); + default: + return false; + } + } + + #getNodeModule() { + if ($app === 'Node.js') { + // biome-ignore lint/style/useNodejsImportProtocol: + const fs = require('fs') + // biome-ignore lint/style/useNodejsImportProtocol: + const path = require('path') + return { fs, path } + } + return null; + } + + #loadData(dataFile: string): StorageData { + const { fs, path } = this.#getNodeModule() ?? {}; + if (!fs || !path) { + return {}; + } + const curDirDataFilePath = path.resolve(dataFile); + const rootDirDataFilePath = path.resolve(process.cwd(), dataFile); + if (fs.existsSync(curDirDataFilePath)) { + return JSON.parse(fs.readFileSync(curDirDataFilePath, 'utf-8')) || {}; + } + if (fs.existsSync(rootDirDataFilePath)) { + return JSON.parse(fs.readFileSync(rootDirDataFilePath, 'utf-8')) || {}; + } + return {}; + } + + #writeData(dataFile: string) { + const { fs, path } = this.#getNodeModule() ?? {}; + if (!fs || !path) { + return + } + const dataFilePath = path.resolve(dataFile); + fs.writeFileSync(dataFilePath, JSON.stringify(this.data), 'utf-8'); + } +} + +// 导出初始化后的实例 +export const Storage = new StorageClass(); \ No newline at end of file diff --git a/src/polyfill/fetch-node.d.ts b/src/polyfill/fetch-node.d.ts deleted file mode 100644 index 489a89b..0000000 --- a/src/polyfill/fetch-node.d.ts +++ /dev/null @@ -1 +0,0 @@ -export const getNodeFetch: () => Promise<{ fetch: typeof import('node-fetch').default }>; diff --git a/src/polyfill/fetch-node.mjs b/src/polyfill/fetch-node.mts similarity index 60% rename from src/polyfill/fetch-node.mjs rename to src/polyfill/fetch-node.mts index e8c037a..75d84c4 100644 --- a/src/polyfill/fetch-node.mjs +++ b/src/polyfill/fetch-node.mts @@ -1,6 +1,6 @@ export const getNodeFetch = () => { const nodeFetch = globalThis.fetch ? globalThis.fetch : require('node-fetch'); - const fetchCookie = globalThis.fetchCookie ? globalThis.fetchCookie : require('fetch-cookie').default; + const fetchCookie = (globalThis as any).fetchCookie ? (globalThis as any).fetchCookie : require('fetch-cookie').default; const fetch = fetchCookie(nodeFetch); return { fetch, diff --git a/src/polyfill/fetch.ts b/src/polyfill/fetch.mts similarity index 96% rename from src/polyfill/fetch.ts rename to src/polyfill/fetch.mts index 7ac317e..151de1a 100644 --- a/src/polyfill/fetch.ts +++ b/src/polyfill/fetch.mts @@ -1,6 +1,6 @@ -import { set } from './Lodash'; -import { $app } from '../lib/app'; -import { StatusTexts } from './StatusTexts'; +import { set } from './Lodash.mjs'; +import { $app } from '../lib/app.mjs'; +import { StatusTexts } from './StatusTexts.mjs'; declare const $task: { fetch: (options: FetchOptions) => Promise; @@ -139,7 +139,7 @@ export async function fetch( } if ($app === 'Node.js') { - const fetch = await import('./fetch-node').then((module) => module.getNodeFetch().then((module) => module.fetch)); + const fetch = await import('./fetch-node.mjs').then((module) => module.getNodeFetch().fetch); // 转换请求参数 params.timeout = (params.timeout ?? 5) * 1000; params.redirect = params.redirection ? 'follow' : 'manual'; diff --git a/src/polyfill/index.mts b/src/polyfill/index.mts new file mode 100644 index 0000000..8d9cf16 --- /dev/null +++ b/src/polyfill/index.mts @@ -0,0 +1,5 @@ +export * from './Console.mjs'; +export * from './fetch.mjs'; +export * from './Lodash.mjs'; +export * from './StatusTexts.mjs'; +export * from './Storage.mjs'; diff --git a/src/polyfill/index.ts b/src/polyfill/index.ts deleted file mode 100644 index 38535d2..0000000 --- a/src/polyfill/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './Console'; -export * from './fetch'; -export * from './Lodash'; -export * from './StatusTexts'; -export * from './Storage'; diff --git a/tsconfig.json b/tsconfig.json index e12f2dd..5ae4d73 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,14 +3,15 @@ "lib": ["ES2021"], "module": "ESNext", "target": "ES2021", - "noEmit": true, + "noEmit": false, "strict": true, "skipLibCheck": true, "isolatedModules": true, "resolveJsonModule": true, "moduleResolution": "bundler", "useDefineForClassFields": true, - "allowImportingTsExtensions": true + "outDir": "./dist", + "declaration": true }, "include": ["src"] -} +} \ No newline at end of file