From 0fb3bfe6a3a3ade367f74ff959689cb4cb782a25 Mon Sep 17 00:00:00 2001 From: aooiuu Date: Mon, 15 Jul 2024 21:13:52 +0800 Subject: [PATCH] refactor: sqlite --- package.json | 6 +- packages/cli/package.json | 2 +- packages/core/package.json | 3 +- packages/rule-utils/src/rule.ts | 24 ++ packages/server/package.json | 5 +- packages/server/src/index.ts | 4 +- packages/server/src/routes.ts | 4 +- packages/shared/build.config.ts | 1 + packages/shared/package.json | 3 +- packages/shared/src/api.ts | 299 ----------------- packages/shared/src/app.ts | 96 ++++++ .../shared/src/controller/BaseController.ts | 14 +- packages/shared/src/controller/Bookshelf.ts | 11 + packages/shared/src/controller/Config.ts | 15 + .../shared/src/controller/ResourceRule.ts | 37 ++- packages/shared/src/controller/RuleManager.ts | 94 ++++++ packages/shared/src/decorators/index.ts | 17 +- packages/shared/src/entity/ChapterHistory.ts | 2 +- .../shared/src/entity/ResourceFavorites.ts | 2 +- packages/shared/src/entity/ResourceHistory.ts | 3 +- packages/shared/src/entity/ResourceRule.ts | 17 +- packages/shared/src/entity/RuleExtra.ts | 7 + packages/shared/src/index.ts | 3 +- .../shared/src/service/ResourceRuleService.ts | 79 ++++- packages/shared/src/utils/ruleFileManager.ts | 95 ------ packages/utools/public/preload.js | 4 +- packages/utools/src/index.ts | 4 +- packages/vscode/package.json | 2 +- packages/vscode/src/webview/WebviewEvent.ts | 4 +- packages/web/electron/api.ts | 4 +- packages/web/package.json | 1 - packages/web/src/api/index.ts | 234 +++++++------- packages/web/src/pages/pc/rules/index.vue | 6 + packages/web/src/router/router.pc.ts | 5 +- pnpm-lock.yaml | 306 +++--------------- 35 files changed, 575 insertions(+), 838 deletions(-) delete mode 100644 packages/shared/src/api.ts create mode 100644 packages/shared/src/app.ts create mode 100644 packages/shared/src/controller/Bookshelf.ts create mode 100644 packages/shared/src/controller/Config.ts create mode 100644 packages/shared/src/controller/RuleManager.ts create mode 100644 packages/shared/src/entity/RuleExtra.ts diff --git a/package.json b/package.json index 25332e86..1fc1d09f 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "*.d.ts" ], "scripts": { - "start": "esno index.ts", + "start": "tsx index.ts", "release": "bumpp -r --no-push", "clean": "rimraf packages/*/dist --glob", "clean:npm": "rimraf packages/*/node_modules --glob && rimraf node_modules", @@ -39,7 +39,6 @@ "run:vsc": "npm-run-all core:build build:web-w", "docs": "npm -C docs run docs:dev", "build:docs": "npm -C docs run docs:build", - "server": "npm -C packages/server run dev", "run:server": "run-p server run:web", "test": "jest", "coveralls": "jest --coverage", @@ -54,6 +53,7 @@ "vscode:build-tpl": "npm -C packages/web run vscode:build", "vscode:build-vsx": "npm -C packages/vscode run build", "vscode:build": "npm-run-all vscode:build-tpl vscode:build-vsx", + "server": "npm -C packages/server run dev", "server:build": "npm -C packages/server run build", "cli:build-tpl": "npm -C packages/web run cli:build", "cli:build-js": "npm -C packages/cli run build", @@ -70,8 +70,10 @@ "@types/mime": "3.0.4", "@types/uuid": "^9.0.8", "bumpp": "^9.4.1", + "cross-env": "^7.0.3", "husky": "^8.0.0", "npm-run-all": "^4.1.5", + "tsx": "^4.16.2", "unbuild": "^2.0.0" }, "lint-staged": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 911ffd6d..dfc9b99c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -11,7 +11,7 @@ "any-reader": "./bin/index.mjs" }, "scripts": { - "build": "esno ./scripts/publish.cjs && unbuild" + "build": "tsx ./scripts/publish.cjs && unbuild" }, "keywords": [], "author": "aooiuu ", diff --git a/packages/core/package.json b/packages/core/package.json index a0e728cc..cb505362 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -22,7 +22,7 @@ "dist" ], "scripts": { - "start": "esno src/start.ts", + "start": "tsx src/start.ts", "build": "unbuild", "stub": "unbuild --stub" }, @@ -45,7 +45,6 @@ "@types/node": "^18.16.19", "@types/xmldom": "^0.1.34", "eslint": "^8.44.0", - "esno": "^0.16.3", "jest": "^29.7.0", "ts-jest": "^29.1.1", "typescript": "^5.1.6" diff --git a/packages/rule-utils/src/rule.ts b/packages/rule-utils/src/rule.ts index 0e34ef86..b1a39fd7 100644 --- a/packages/rule-utils/src/rule.ts +++ b/packages/rule-utils/src/rule.ts @@ -134,3 +134,27 @@ export function createRule(rule: Rule | any): Rule { viewStyle: 0, }, rule) } + +/** + * + * @param {string} str + * @returns {boolean} + */ +export function isEsoStr(str: string): boolean { + return str.startsWith('eso://') +} + +/** + * + * @param rule + * @returns {boolean} + */ +export function isRule(rule: any): boolean { + if (typeof rule === 'string') + return isEsoStr(rule) + + if (typeof rule !== 'object') + return false + + return rule.id && rule.host && typeof rule.contentType !== 'undefined' +} diff --git a/packages/server/package.json b/packages/server/package.json index d6830052..4977e53c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -24,7 +24,7 @@ "scripts": { "build": "unbuild", "test": "echo \"Error: no test specified\" && exit 1", - "dev": "esno watch src/run.ts" + "dev": "tsx watch src/run.ts" }, "dependencies": { "@any-reader/core": "workspace:^", @@ -43,7 +43,6 @@ "@types/koa-router": "^7.4.8", "@types/koa-session": "^6.4.5", "@types/koa-static": "^4.0.4", - "@types/koa__cors": "^5.0.0", - "esno": "^0.16.3" + "@types/koa__cors": "^5.0.0" } } diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 2de6d533..51ea9f1b 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -6,7 +6,7 @@ import { bodyParser } from '@koa/bodyparser' import cors from '@koa/cors' import serve from 'koa-static' import session from 'koa-session' -import { Api } from '@any-reader/shared' +import { createApp } from '@any-reader/shared' import { createRoute } from './routes' const __filename = fileURLToPath(import.meta.url) @@ -18,7 +18,7 @@ const CONFIG_PATH = path.join(ROOT_PATH, 'config.desktop.json') const app = new Koa() export async function start(port = 8898, root = resolve(__dirname, 'public')) { - const api = new Api({ + const api = createApp({ configPath: CONFIG_PATH, }) const router = createRoute(api) diff --git a/packages/server/src/routes.ts b/packages/server/src/routes.ts index fb609fb3..2b30fddc 100644 --- a/packages/server/src/routes.ts +++ b/packages/server/src/routes.ts @@ -1,8 +1,8 @@ import Router from 'koa-router' import bcrypt from 'bcryptjs' -import type { Api } from '@any-reader/shared' +import type { App } from '@any-reader/shared' -export function createRoute(api: Api) { +export function createRoute(api: App) { const router = new Router() router.post('/login', (ctx) => { diff --git a/packages/shared/build.config.ts b/packages/shared/build.config.ts index ccc3a5b3..43d40308 100644 --- a/packages/shared/build.config.ts +++ b/packages/shared/build.config.ts @@ -5,6 +5,7 @@ export default defineBuildConfig({ externals: [], clean: true, declaration: true, + sourcemap: true, rollup: { inlineDependencies: true, emitCJS: true, diff --git a/packages/shared/package.json b/packages/shared/package.json index 5bb2d595..4769cc6d 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -25,7 +25,7 @@ "scripts": { "build": "unbuild", "stub": "unbuild --stub", - "start": "esno src/start.ts" + "start": "tsx src/start.ts" }, "dependencies": { "@any-reader/core": "workspace:^", @@ -50,7 +50,6 @@ "@types/encoding-japanese": "^2.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^18.16.19", - "esno": "^0.16.3", "reflect-metadata": "^0.2.2", "rollup": "^3.26.0", "rollup-plugin-dts": "^5.3.0", diff --git a/packages/shared/src/api.ts b/packages/shared/src/api.ts deleted file mode 100644 index b2f9c49d..00000000 --- a/packages/shared/src/api.ts +++ /dev/null @@ -1,299 +0,0 @@ -import { merge } from 'lodash-es' - -// @ts-expect-error -import { ensureFileSync, readJSONSync, writeJSONSync } from 'fs-extra/esm' -import type { Rule } from '@any-reader/rule-utils' -import { ContentType } from '@any-reader/rule-utils' -import { RuleManager } from '@any-reader/core' -import { LOCAL_BOOK_DIR } from './constants' -import * as ruleFileManager from './utils/ruleFileManager' -import * as ruleExtraManager from './utils/ruleExtraManager' -import type { BookChapter } from './utils/localBookManager' -import localBookManager from './utils/localBookManager' -import { db } from './data-source' -import { ChapterHistory } from './controller/ChapterHistory' -import { ResourceHistory } from './controller/ResourceHistory' -import { ResourceFavorites } from './controller/ResourceFavorites' -import { ResourceRule } from './controller/ResourceRule' -import { mapRoute } from './decorators' - -// 发现页分类 -async function discoverMap(ruleId: string) { - const rule = await ruleFileManager.findById(ruleId) - const ruleManager = new RuleManager(rule) - return ruleManager.discoverMap() -} - -/** - * 发现页列表 - * @returns - */ -async function discover({ ruleId, data }: any) { - const rule = await ruleFileManager.findById(ruleId) - const ruleManager = new RuleManager(rule) - return ruleManager.discover(data.value) -} - -/** - * 本地书籍 - * @returns - */ -function getLocalBooks(dir: string) { - return localBookManager.getBookList(dir) -} - -/** - * 规则列表 - * @returns - */ -function rules() { - return ruleFileManager.list() -} - -function batchUpdateRules(data: { ids: string[]; rule: Rule }) { - return ruleFileManager.batchUpdate(data) -} - -/** - * 根据规则ID获取规则 - * @param ruleId - * @returns - */ -async function getRuleById(ruleId: string) { - const rules = await ruleFileManager.list() - return rules.find(e => e.id === ruleId) -} - -/** - * 创建规则 - * @param data - * @returns - */ -function createRule(data: Rule) { - return ruleFileManager.update(data) -} - -/** - * 更新规则 - * @param data - * @returns - */ -async function updateRule(data: Rule) { - await ruleFileManager.update(data) - return data -} - -/** - * 搜索 - * @returns - */ -async function searchByRuleId({ ruleId, keyword }: { ruleId: string; keyword: string }) { - const rule = await ruleFileManager.findById(ruleId) - const analyzer = new RuleManager(rule) - return await analyzer.search(keyword).catch(() => []) -} - -/** - * 获取内容 - * @param param0 - * @returns - */ -async function content({ filePath, chapterPath, ruleId }: any) { - // 在线 - if (ruleId) { - const rule = await ruleFileManager.findById(ruleId) - const rm = new RuleManager(rule) - const content: string[] = await rm.getContent(chapterPath).catch(() => []) - let text = '' - if (rule.contentType === ContentType.MANGA) - text = content.map(src => ``).join('') - else if (rule.contentType === ContentType.VIDEO) - text = content?.[0] || '' - else - text = content.join('\n') - - return { - content: text, - } - } - // 本地 - const content = await localBookManager.getContent(toBookChapter(filePath, chapterPath)) - return { - content, - } -} - -/** - * 获取章节列表 - * @returns - */ -async function getChapter({ filePath = '', ruleId = undefined } = {}) { - if (ruleId) { - const rule = await ruleFileManager.findById(ruleId) - const rm = new RuleManager(rule) - const list = await rm.getChapter(filePath).catch(() => []) - return list.map((e: any) => ({ - ...e, - name: e.name, - chapterPath: e.url, - }), - ) - } - // 本地 - return localBookManager.getChapter(filePath) -} - -/** - * 转换为 BookChapter - * @param filePath 文件路径 - * @param chapterPath 章节路径 - * @returns - */ -function toBookChapter(filePath: string, chapterPath: string): BookChapter { - return { - name: '', - chapterPath, - filePath, - } -} - -function getRuleExtras() { - return ruleExtraManager.getRuleExtras() -} - -function ping(data: { id: string; host: string }) { - return ruleExtraManager.ping(data.id, data.host) -} - -// 删除规则 -async function delRules(data: { id: string[] }) { - await ruleFileManager.del(data.id, true) -} - -function success(data: any, msg = '') { - return { - code: 0, - data, - msg, - } -} - -export class Api { - configPath: string - defaultConfig: any - config: any - - constructor(params: { configPath: string; defaultConfig?: any }) { - this.configPath = params.configPath - this.defaultConfig = params.defaultConfig ?? {} - this.readConfig() - return this - } - - readConfig() { - ensureFileSync(this.configPath) - let config = {} - try { - config = readJSONSync(this.configPath) - } - catch (error) { - console.warn(error) - } - this.config = merge(this.defaultConfig, config) - if (!this.config.bookDir) - this.config.bookDir = LOCAL_BOOK_DIR - } - - async updateConfig(data: any) { - ensureFileSync(this.configPath) - this.config = merge(this.config, data || {}) - writeJSONSync(this.configPath, this.config, { spaces: 2 }) - } - - get bookDir(): string { - return this.config.bookDir - } - - async useApi(register: any) { - await db.initialize() - - const registerApi = async (apiPath: string, handle: (...arg: any) => Promise, log?: { - ruleId: (...arg: any) => string - check: (arg: any) => boolean - }) => { - register(apiPath, async (...arg: any) => { - // 原始返回值 - const result = await handle(...arg).catch(() => {}) - - // 记录接口调用情况 - if (typeof log === 'object' && log.ruleId && log.check) { - const ruleId = log.ruleId(...arg) - - // 不记录没有规则ID的接口 - if (ruleId) { - const isOk = log.check(result) - ruleExtraManager.updateApiStatus(ruleId, isOk ? `${apiPath}.ok` : `${apiPath}.fail`) - } - } - - // 返回数据 - return success(result) - }) - } - - const discoverLog = { - ruleId: (data: any) => data.ruleId, - check: (v: any[]) => Array.isArray(v) && v.length > 0, - } - - const contentLog = { - ruleId: (data: any) => data.ruleId, - check: (v: any) => v?.content?.length > 0, - } - - registerApi('get@discoverMap', async ({ ruleId = '' } = {}) => await discoverMap(ruleId), discoverLog) - registerApi('post@discover', async (data: any) => await discover(data), discoverLog) - registerApi('post@searchByRuleId', async (data: any) => await searchByRuleId(data), discoverLog) - registerApi('post@getChapter', async (data: any) => await getChapter(data), discoverLog) - registerApi('post@content', async (data: any) => await content(data), contentLog) - - // 配置 - registerApi('get@readConfig', async () => this.config) - registerApi('post@updateConfig', async (data: any) => await this.updateConfig(data)) - - // 本地 - registerApi('get@getLocalBooks', async () => await getLocalBooks(this.bookDir)) - - // 规则 - registerApi('post@createRule', async (data: any) => await createRule(data)) - registerApi('post@updateRule', async (data: any) => await updateRule(data)) - registerApi('get@rules', async () => await rules()) - registerApi('get@getRuleById', async ({ id = '' } = {}) => await getRuleById(id)) - registerApi('get@getRuleExtras', async () => await getRuleExtras()) - registerApi('post@batchUpdateRules', async (data: any) => await batchUpdateRules(data)) - registerApi('post@delRules', async (data: any) => await delRules(data)) - registerApi('post@updateRuleSort', async (data: any) => await ruleFileManager.updateRuleSort(data && data.id)) - registerApi('post@importRules', async (data: any) => await ruleFileManager.importRules(data && data.url)) - registerApi('post@importCMS', async (data: any) => await ruleFileManager.importCMS(data)) - registerApi('post@ping', async (data: any) => await ping(data)) - - const app = { - controllers: [ - ChapterHistory, - ResourceHistory, - ResourceFavorites, - ResourceRule, - ], - } - - for (const Controller of app.controllers) { - const routes = mapRoute(Controller) - for (const route of routes) { - registerApi([route.method, route.route].join('@'), (...arg: any) => { - const instance: any = new Controller(db) - return instance[route.methodName](...arg) - }) - } - } - } -} diff --git a/packages/shared/src/app.ts b/packages/shared/src/app.ts new file mode 100644 index 00000000..47380491 --- /dev/null +++ b/packages/shared/src/app.ts @@ -0,0 +1,96 @@ +import { merge } from 'lodash-es' + +// @ts-expect-error +import { ensureFileSync, readJSONSync, writeJSONSync } from 'fs-extra/esm' +import { LOCAL_BOOK_DIR } from './constants' +import type { DB } from './data-source' +import { db } from './data-source' +import { ChapterHistory } from './controller/ChapterHistory' +import { ResourceHistory } from './controller/ResourceHistory' +import { ResourceFavorites } from './controller/ResourceFavorites' +import { ResourceRule } from './controller/ResourceRule' +import { RuleManager } from './controller/RuleManager' +import { Bookshelf } from './controller/Bookshelf' +import { Config } from './controller/Config' +import { mapRoute } from './decorators' + +export interface App { + db: DB + config: any + configPath: any + controllers: any[] + updateConfig: (data: any) => void + readConfig: () => void + useApi: (register: any) => void +} + +export function createApp(params: { configPath: string; defaultConfig?: any }): App { + const defConfig = params.defaultConfig ?? {} + + const app: App = { + db, + config: {}, + configPath: params.configPath, + + controllers: [ + ChapterHistory, + ResourceHistory, + ResourceFavorites, + ResourceRule, + RuleManager, + Bookshelf, + Config, + ], + + updateConfig(data: any) { + ensureFileSync(app.configPath) + app.config = merge(app.config, data || {}) + writeJSONSync(app.configPath, app.config, { spaces: 2 }) + }, + + readConfig() { + ensureFileSync(app.configPath) + let config = {} + try { + config = readJSONSync(app.configPath) + } + catch (error) { + console.warn(error) + } + app.config = merge(defConfig, config) + if (!app.config.bookDir) + app.config.bookDir = LOCAL_BOOK_DIR + }, + + useApi(register: any) { + runApp(app, register) + }, + } + + app.readConfig() + return app +} + +async function runApp(app: App, register: any) { + await app.db.initialize() + + for (const Controller of app.controllers) { + const routes = mapRoute(Controller) + for (const route of routes) { + register([route.method, route.route].join('@'), async (...arg: any) => { + const instance: any = new Controller(app) + return await instance[route.methodName](...arg) + .then((res: any) => success(res)) + .catch((res: Error) => success([], res?.message || 'error', -1)) + }) + } + } +} + +function success(data: any, msg = '', code = 0) { + return { + code, + data, + msg, + } +} diff --git a/packages/shared/src/controller/BaseController.ts b/packages/shared/src/controller/BaseController.ts index dd42df54..055412fd 100644 --- a/packages/shared/src/controller/BaseController.ts +++ b/packages/shared/src/controller/BaseController.ts @@ -1,12 +1,16 @@ -import type { DB } from '../data-source' +import type { App } from '../app' export class BaseController { - private _db: DB - constructor(db: DB) { - this._db = db + private _app: App + constructor(app: App) { + this._app = app + } + + get app() { + return this._app } get db() { - return this._db + return this.app.db } } diff --git a/packages/shared/src/controller/Bookshelf.ts b/packages/shared/src/controller/Bookshelf.ts new file mode 100644 index 00000000..5c1ffbe2 --- /dev/null +++ b/packages/shared/src/controller/Bookshelf.ts @@ -0,0 +1,11 @@ +import { Controller, Post } from '../decorators' +import localBookManager from '../utils/localBookManager' +import { BaseController } from './BaseController' + +@Controller('/bookshelf') +export class Bookshelf extends BaseController { + @Post('list') + read() { + return localBookManager.getBookList(this.app.config.bookDir) + } +} diff --git a/packages/shared/src/controller/Config.ts b/packages/shared/src/controller/Config.ts new file mode 100644 index 00000000..33385588 --- /dev/null +++ b/packages/shared/src/controller/Config.ts @@ -0,0 +1,15 @@ +import { Controller, Post } from '../decorators' +import { BaseController } from './BaseController' + +@Controller('/config') +export class Config extends BaseController { + @Post('read') + async read() { + return this.app.config + } + + @Post('save') + async list(data: any) { + return this.app.updateConfig(data) + } +} diff --git a/packages/shared/src/controller/ResourceRule.ts b/packages/shared/src/controller/ResourceRule.ts index 6780a592..2d03c1eb 100644 --- a/packages/shared/src/controller/ResourceRule.ts +++ b/packages/shared/src/controller/ResourceRule.ts @@ -1,4 +1,3 @@ -import { type Rule, cmsJsonToRule, cmsXmlToRule } from '@any-reader/rule-utils' import { Controller, Post } from '../decorators' import { BaseController } from './BaseController' @@ -10,6 +9,11 @@ export class ResourceRule extends BaseController { return this.db.getResourceRule().list() } + @Post('find-by-id') + findById(arg: any) { + return this.db.getResourceRule().findById(arg.id) + } + // 添加 @Post('create') create(arg: any) { @@ -25,28 +29,23 @@ export class ResourceRule extends BaseController { // 删除 @Post('remove-by-id') removeById(arg: any) { - return this.db.getResourceRule().removeById(arg) + return this.db.getResourceRule().removeById(arg.id) } @Post('import-cms') - async importCMS(params: ImportCMSParams) { - let rule = {} as Rule - if (params.type === 'maccms.json') - rule = await cmsJsonToRule(params.api) - else if (params.type === 'maccms.xml') - rule = await cmsXmlToRule(params.api) - else - throw new Error('未知的规则类型') - - Object.assign(rule, { name: params.name }) - return await this.save(rule) + importCMS(arg: any) { + return this.db.getResourceRule().importCMS(arg) } - // 排序 -} + @Post('import') + import(arg: any) { + return this.db.getResourceRule().importRules(arg.url) + } -interface ImportCMSParams { - type: string - name: string - api: string + @Post('batch-update') + batchUpdateRules({ ids, rule }: { ids: number[]; rule: any }) { + return this.db.getResourceRule().repository.update(ids, { + ...rule, + }) + } } diff --git a/packages/shared/src/controller/RuleManager.ts b/packages/shared/src/controller/RuleManager.ts new file mode 100644 index 00000000..a1d84809 --- /dev/null +++ b/packages/shared/src/controller/RuleManager.ts @@ -0,0 +1,94 @@ +import { RuleManager as RM } from '@any-reader/core' +import { ContentType } from '@any-reader/rule-utils' +import { Controller, Post } from '../decorators' +import type { BookChapter } from '../utils/localBookManager' +import localBookManager from '../utils/localBookManager' +import { BaseController } from './BaseController' + +@Controller('/rule-manager') +export class RuleManager extends BaseController { + @Post('discover-map') + async discoverMap(arg: { ruleId: string }) { + const rule = await this.getRule(arg.ruleId) + const ruleManager = new RM(rule) + return await ruleManager.discoverMap() + } + + @Post('discover') + async discover(arg: { ruleId: string; data: any }) { + const rule = await this.getRule(arg.ruleId) + const ruleManager = new RM(rule) + return ruleManager.discover(arg.data.value) + } + + @Post('search-by-rule-id') + async searchByRuleId(arg: { ruleId: string; keyword: string }) { + const rule = await this.getRule(arg.ruleId) + const analyzer = new RM(rule) + return await analyzer.search(arg.keyword) + } + + @Post('chapter') + async getChapter({ ruleId, filePath }: { ruleId?: string; filePath: string }) { + if (ruleId) { + const rule = await this.getRule(ruleId) + const rm = new RM(rule) + const list = await rm.getChapter(filePath).catch(() => []) + return list.map((e: any) => ({ + ...e, + name: e.name, + chapterPath: e.url, + }), + ) + } + // 本地 + return localBookManager.getChapter(filePath) + } + + @Post('content') + async content({ filePath, chapterPath, ruleId }: any) { + // 在线 + if (ruleId) { + const rule = await this.getRule(ruleId) + const rm = new RM(rule) + const content: string[] = await rm.getContent(chapterPath).catch(() => []) + let text = '' + if (rule.contentType === ContentType.MANGA) + text = content.map(src => ``).join('') + else if (rule.contentType === ContentType.VIDEO) + text = content?.[0] || '' + else + text = content.join('\n') + + return { + content: text, + } + } + // 本地 + const content = await localBookManager.getContent(toBookChapter(filePath, chapterPath)) + return { + content, + } + } + + private async getRule(ruleId: string) { + const rule = await this.db.getResourceRule().findById(ruleId) + if (!rule) + throw new Error('规则不存在') + return rule + } +} + +/** + * 转换为 BookChapter + * @param filePath 文件路径 + * @param chapterPath 章节路径 + * @returns + */ +function toBookChapter(filePath: string, chapterPath: string): BookChapter { + return { + name: '', + chapterPath, + filePath, + } +} diff --git a/packages/shared/src/decorators/index.ts b/packages/shared/src/decorators/index.ts index dc8b941e..2b0850e4 100644 --- a/packages/shared/src/decorators/index.ts +++ b/packages/shared/src/decorators/index.ts @@ -24,7 +24,9 @@ const defaultMetadata = { [METHOD_METADATA]: RequestMethod.GET, } -function RequestMapping(metadata: RequestMappingMetadata = defaultMetadata): MethodDecorator { +function RequestMapping( + metadata: RequestMappingMetadata = defaultMetadata, +): MethodDecorator { const pathMetadata = metadata[PATH_METADATA] const path = pathMetadata && pathMetadata.length ? pathMetadata : '/' const requestMethod = metadata[METHOD_METADATA] || RequestMethod.GET @@ -63,10 +65,12 @@ export function mapRoute(controller: object): Route[] { const prototype = instance.prototype const basePath: string = Reflect.getMetadata(PATH_METADATA, controller) - const methodsNames = Object.getOwnPropertyNames(prototype) - .filter( - item => !isConstructor(item) && isFunction(prototype[item]), - ) + const methodsNames = Object.getOwnPropertyNames(prototype).filter( + methodName => + !isConstructor(methodName) + && isFunction(prototype[methodName]) + && Reflect.getMetadata(PATH_METADATA, prototype[methodName]), + ) return methodsNames.map((methodName) => { const fn = prototype[methodName] @@ -74,8 +78,7 @@ export function mapRoute(controller: object): Route[] { let route = basePath.replace(/^\//, '') // 移出前缀斜杠 if (methodPath.startsWith('/')) route = methodPath // 方法定义完整路径 - else - route = `${route}/${methodPath}` // 补充 controller 路径 + else route = `${route}/${methodPath}` // 补充 controller 路径 const method = Reflect.getMetadata(METHOD_METADATA, fn) return { diff --git a/packages/shared/src/entity/ChapterHistory.ts b/packages/shared/src/entity/ChapterHistory.ts index 73efb383..10d48f85 100644 --- a/packages/shared/src/entity/ChapterHistory.ts +++ b/packages/shared/src/entity/ChapterHistory.ts @@ -1,7 +1,7 @@ import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' @Entity({ name: 'chapter_history' }) -@Index(['ruleId', 'filePath', 'chapterPath'], { unique: true }) +@Index(['uid', 'ruleId', 'filePath', 'chapterPath'], { unique: true }) export class ChapterHistory { @PrimaryGeneratedColumn() id!: number diff --git a/packages/shared/src/entity/ResourceFavorites.ts b/packages/shared/src/entity/ResourceFavorites.ts index 1cc03d89..007c07c6 100644 --- a/packages/shared/src/entity/ResourceFavorites.ts +++ b/packages/shared/src/entity/ResourceFavorites.ts @@ -1,7 +1,7 @@ import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' @Entity({ name: 'resource_favorites' }) -@Index(['ruleId', 'url'], { unique: true }) +@Index(['uid', 'ruleId', 'url'], { unique: true }) export class ResourceFavorites { @PrimaryGeneratedColumn() id!: number diff --git a/packages/shared/src/entity/ResourceHistory.ts b/packages/shared/src/entity/ResourceHistory.ts index d1c1393d..0462ec26 100644 --- a/packages/shared/src/entity/ResourceHistory.ts +++ b/packages/shared/src/entity/ResourceHistory.ts @@ -1,7 +1,7 @@ import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' @Entity({ name: 'resource_history' }) -@Index(['ruleId', 'url'], { unique: true }) +@Index(['uid', 'ruleId', 'url'], { unique: true }) export class ResourceHistory { @PrimaryGeneratedColumn() id!: number @@ -16,6 +16,7 @@ export class ResourceHistory { url!: string // ===================================================== + @Column({ name: 'name', type: 'text', default: '' }) name!: string diff --git a/packages/shared/src/entity/ResourceRule.ts b/packages/shared/src/entity/ResourceRule.ts index 1f7fce59..b2740d43 100644 --- a/packages/shared/src/entity/ResourceRule.ts +++ b/packages/shared/src/entity/ResourceRule.ts @@ -5,15 +5,12 @@ export class ResourceRule { @PrimaryGeneratedColumn('uuid') id!: string - @Column({ name: 'uid', type: 'integer', default: 0 }) - uid!: number - @Column({ name: 'enable_upload', type: 'integer', default: 0, transformer: { - to: v => v ? 1 : 0, + to: v => (v ? 1 : 0), from: v => !!v, }, }) @@ -65,7 +62,7 @@ export class ResourceRule { type: 'integer', default: 0, transformer: { - to: v => v ? 1 : 0, + to: v => (v ? 1 : 0), from: v => !!v, }, }) @@ -83,7 +80,7 @@ export class ResourceRule { type: 'integer', default: 0, transformer: { - to: v => v ? 1 : 0, + to: v => (v ? 1 : 0), from: v => !!v, }, }) @@ -147,8 +144,12 @@ export class ResourceRule { @Column({ name: 'enable_search', - type: 'text', + type: 'integer', default: '', + transformer: { + to: v => (v ? 1 : 0), + from: v => !!v, + }, }) enableSearch!: boolean @@ -248,7 +249,7 @@ export class ResourceRule { type: 'integer', default: 0, transformer: { - to: v => v ? 1 : 0, + to: v => (v ? 1 : 0), from: v => !!v, }, }) diff --git a/packages/shared/src/entity/RuleExtra.ts b/packages/shared/src/entity/RuleExtra.ts new file mode 100644 index 00000000..cecb7a90 --- /dev/null +++ b/packages/shared/src/entity/RuleExtra.ts @@ -0,0 +1,7 @@ +import { Entity, PrimaryGeneratedColumn } from 'typeorm' + +@Entity({ name: 'rule_extra' }) +export class RuleExtra { + @PrimaryGeneratedColumn() + id!: number +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 28d8382c..548c8a75 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,3 +1,2 @@ -export * as ruleFileManager from './utils/ruleFileManager' export * as CONSTANTS from './constants' -export { Api } from './api' +export * from './app' diff --git a/packages/shared/src/service/ResourceRuleService.ts b/packages/shared/src/service/ResourceRuleService.ts index 883d764d..41322aec 100644 --- a/packages/shared/src/service/ResourceRuleService.ts +++ b/packages/shared/src/service/ResourceRuleService.ts @@ -1,4 +1,7 @@ import type { Repository } from 'typeorm' +import axios from 'axios' +import type { Rule } from '@any-reader/rule-utils' +import { cmsJsonToRule, cmsXmlToRule, decodeRule, isEsoStr, isRule } from '@any-reader/rule-utils' import type { ResourceRule } from '../entity/ResourceRule' export class ResourceRuleService { @@ -13,10 +16,16 @@ export class ResourceRuleService { order: { modifiedTime: 'DESC', }, - take: 100, + // take: 100, }) } + findById(id: string): Promise { + return this.repository.findOneBy({ + id, + }) as Promise + } + // 删除一个记录 removeById(id: string) { return this.repository.delete({ @@ -43,4 +52,72 @@ export class ResourceRuleService { return await this.repository.save(entity) } } + + async importCMS(params: ImportCMSParams) { + let rule = {} as Rule + if (params.type === 'maccms.json') + rule = await cmsJsonToRule(params.api) + else if (params.type === 'maccms.xml') + rule = await cmsXmlToRule(params.api) + else + throw new Error('未知的规则类型') + + Object.assign(rule, { name: params.name }) + return await this.save(rule) + } + + async importRules(url: string) { + if (typeof url !== 'string') + return + // 单个压缩规则 + if (isEsoStr(url)) { + await this.save(decodeRule(url.trim())).catch(() => {}) + return 1 + } + // 网络地址 + if (/^https?:\/\/.{3,}/.test(url)) { + const res = await axios.create().get(url).catch((e) => { + console.warn(e) + }) + if (!res || Array.isArray(res?.data)) + return + + for (const rule of res.data) { + if (isRule(rule)) + await this.save(rule).catch(() => {}) + } + return res.data.length + } + // json 字符串 + let json + try { + json = JSON.parse(url) + } + catch (error) { + console.warn('导入格式不支持') + } + if (typeof json !== 'object') + return 0 + const jsons = Array.isArray(json) ? json : [json] + for (let json of jsons) { + if (typeof json === 'string' && isEsoStr(json)) { + try { + json = decodeRule(json) + } + catch (error) { + console.warn(error) + continue + } + } + if (isRule(json)) + await this.save(json).catch(() => {}) + } + return jsons.length + } +} + +interface ImportCMSParams { + type: string + name: string + api: string } diff --git a/packages/shared/src/utils/ruleFileManager.ts b/packages/shared/src/utils/ruleFileManager.ts index 9a4d3c57..c8d9a9d8 100644 --- a/packages/shared/src/utils/ruleFileManager.ts +++ b/packages/shared/src/utils/ruleFileManager.ts @@ -4,9 +4,7 @@ import { v4 as uuidV4 } from 'uuid' import _ from 'lodash-es' import type { Low } from 'lowdb/lib' import { JSONFilePreset } from 'lowdb/node' -import axios from 'axios' import type { Rule } from '@any-reader/rule-utils' -import { cmsJsonToRule, cmsXmlToRule, decodeRule } from '@any-reader/rule-utils' import { BOOK_SOURCE_PATH } from '../constants' let mDb: Low @@ -26,15 +24,6 @@ const writeDB = _.throttle(async () => { db.write() }, 1000) -/** - * - * @param {string} str - * @returns {boolean} - */ -function isESO(str: string): boolean { - return str.startsWith('eso://') -} - export async function list(): Promise { const db = await getDb() return db.data @@ -93,87 +82,3 @@ export async function updateRuleSort(ids: string[]) { } writeDB() } - -/** - * - * @param rule - * @returns {boolean} - */ -export function isRule(rule: any): boolean { - if (typeof rule === 'string') - return isESO(rule) - - if (typeof rule !== 'object') - return false - - return rule.id && rule.host && typeof rule.contentType !== 'undefined' -} - -export async function importRules(url: string) { - if (typeof url !== 'string') - return - // 单个压缩规则 - if (isESO(url)) { - await update(decodeRule(url.trim())).catch(() => {}) - return 1 - } - // 网络地址 - if (/^https?:\/\/.{3,}/.test(url)) { - const res = await axios.create().get(url).catch((e) => { - console.warn(e) - }) - if (!res || Array.isArray(res?.data)) - return - - for (const rule of res.data) { - if (isRule(rule)) - await update(rule).catch(() => {}) - } - return res.data.length - } - // json 字符串 - let json - try { - json = JSON.parse(url) - } - catch (error) { - console.warn('导入格式不支持') - } - if (typeof json !== 'object') - return 0 - const jsons = Array.isArray(json) ? json : [json] - for (let json of jsons) { - if (typeof json === 'string' && isESO(json)) { - try { - json = decodeRule(json) - } - catch (error) { - console.warn(error) - continue - } - } - if (isRule(json)) - await update(json).catch(() => {}) - } - return jsons.length -} - -interface ImportCMSParams { - type: string - name: string - api: string -} - -export async function importCMS(params: ImportCMSParams) { - let rule = {} as Rule - if (params.type === 'maccms.json') - rule = await cmsJsonToRule(params.api) - else if (params.type === 'maccms.xml') - rule = await cmsXmlToRule(params.api) - else - throw new Error('未知的规则类型') - - Object.assign(rule, { name: params.name }) - await update(rule) - return 1 -} diff --git a/packages/utools/public/preload.js b/packages/utools/public/preload.js index 0e6fead9..e7b129ce 100644 --- a/packages/utools/public/preload.js +++ b/packages/utools/public/preload.js @@ -1,6 +1,6 @@ const path = require('node:path') const os = require('node:os') -const Api = require('./libs') +const createApp = require('./libs') const ROOT_PATH = path.join(os.homedir(), '.any-reader') const CONFIG_PATH = path.join(ROOT_PATH, 'config.desktop.json') @@ -16,7 +16,7 @@ window.$AnyReader = { }, } -const api = new Api({ +const api = createApp({ configPath: CONFIG_PATH, }) diff --git a/packages/utools/src/index.ts b/packages/utools/src/index.ts index 3ffbb029..8ce6e346 100644 --- a/packages/utools/src/index.ts +++ b/packages/utools/src/index.ts @@ -1,3 +1,3 @@ -import { Api } from '@any-reader/shared' +import { createApp } from '@any-reader/shared' -export default Api +export default createApp diff --git a/packages/vscode/package.json b/packages/vscode/package.json index 80e91545..732b7f29 100644 --- a/packages/vscode/package.json +++ b/packages/vscode/package.json @@ -35,7 +35,7 @@ ], "main": "./dist/extension.js", "scripts": { - "build:rename": "esno ./scripts/publish.cjs", + "build:rename": "tsx ./scripts/publish.cjs", "build:vsce": "vsce package --no-dependencies", "build": "npm-run-all build:rename build:vsce", "vscode:prepublish": "pnpm run package", diff --git a/packages/vscode/src/webview/WebviewEvent.ts b/packages/vscode/src/webview/WebviewEvent.ts index 66c60087..d135ff71 100644 --- a/packages/vscode/src/webview/WebviewEvent.ts +++ b/packages/vscode/src/webview/WebviewEvent.ts @@ -6,7 +6,7 @@ import * as os from 'node:os'; import * as path from 'node:path'; import * as vscode from 'vscode'; import * as EasyPostMessage from 'easy-post-message'; -import { Api } from '@any-reader/shared'; +import { createApp } from '@any-reader/shared'; import { createAdapter } from '../utils/easyPostMessage'; export const ROOT_PATH = path.join(os.homedir(), '.any-reader'); @@ -28,7 +28,7 @@ export class WebviewEvent { // vsc this._pm.answer('post@vscode/executeCommand', this.executeCommand.bind(this)); - new Api({ + createApp({ configPath: CONFIG_PATH }).useApi(this._pm.answer.bind(this._pm)); } diff --git a/packages/web/electron/api.ts b/packages/web/electron/api.ts index b18d6f00..c78b0fe5 100644 --- a/packages/web/electron/api.ts +++ b/packages/web/electron/api.ts @@ -3,7 +3,7 @@ import * as path from 'node:path'; import { BrowserWindow, app } from 'electron'; import EasyPostMessage from 'easy-post-message'; import Adapter from 'easy-post-message/electron-adapter'; -import { Api } from '@any-reader/shared'; +import { createApp } from '@any-reader/shared'; export const ROOT_PATH = path.join(os.homedir(), '.any-reader'); export const CONFIG_PATH = path.join(ROOT_PATH, 'config.desktop.json'); @@ -19,7 +19,7 @@ function success(data: any, msg = '') { export function createAPI() { const pm = new EasyPostMessage(Adapter); - new Api({ + createApp({ configPath: CONFIG_PATH }).useApi(pm.answer.bind(pm)); diff --git a/packages/web/package.json b/packages/web/package.json index 26613166..7267564b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -82,7 +82,6 @@ "@vue/eslint-config-typescript": "^12.0.0", "@vue/tsconfig": "^0.5.1", "chalk": "^5.2.0", - "cross-env": "^7.0.3", "electron": "30.0.6", "electron-builder": "^24.13.3", "electron-rebuild": "^3.2.9", diff --git a/packages/web/src/api/index.ts b/packages/web/src/api/index.ts index bf849411..373b20c3 100644 --- a/packages/web/src/api/index.ts +++ b/packages/web/src/api/index.ts @@ -1,259 +1,275 @@ import { request } from '@/utils/request'; -// 获取所有规则 -export function getRules() { - return request({ - method: 'get', - url: 'rules' - }); -} - -// 根据ID获取规则 -export function getRuleById(id: string) { +// 获取扩展数据 +export function getRuleExtras() { return request({ method: 'get', - url: 'getRuleById', - params: { id } + url: 'getRuleExtras' }); } -// 创建规则 -export function createRule(data: any) { +// 测速 +export function ping(data: any) { return request({ method: 'post', - url: 'createRule', + url: 'ping', data }); } -// 更新规则 -export function updateRule(data: any) { +// 更新排序 +export function updateRuleSort(data: any) { return request({ method: 'post', - url: 'updateRule', + url: 'updateRuleSort', data }); } -// 发现页分类列表 -export function discoverMap(ruleId: string) { +// ====================================== +// =============== WEB =============== +// ====================================== + +export function install(data: { password: string }) { return request({ - method: 'get', - url: 'discoverMap', - params: { - ruleId - } + method: 'post', + url: 'install', + data }); } -// 发现页分类下内容 -export function discover(data: any) { +export function login(data: { password: string }) { return request({ method: 'post', - url: 'discover', + url: 'login', data }); } -// 获取本地 -export function getLocalBooks() { +export function logout() { return request({ method: 'get', - url: 'getLocalBooks' + url: 'logout' }); } -// 根据规则ID搜索内容 -export function searchByRuleId(data: { ruleId: string; keyword: string }) { +// ====================================== +// =============== 历史 =============== +// ====================================== + +// 获取历史 +export function getHistory() { return request({ method: 'post', - url: 'searchByRuleId', - data + url: 'resource-history/list' }); } -// 获取内容 -export function getContent(data: any) { +// 删除历史 +export function removeHistory(data: { ruleId: string; url: string }) { return request({ method: 'post', - url: 'content', + url: 'resource-history/remove', data }); } -// 获取章节 -export function getChapter(filePath: string, ruleId?: string) { +// 添加历史 +export function addHistory(data: any) { return request({ method: 'post', - url: 'getChapter', - data: { - filePath, - ruleId - } + url: 'resource-history/add', + data }); } -// 获取配置 -export function readConfig() { +// ====================================== +// =============== 收藏 =============== +// ====================================== + +// 获取收藏列表 +export function getFavorites() { return request({ - method: 'get', - url: 'readConfig' + method: 'post', + url: 'resource-favorites/list' }); } - -// 更新配置 -export function updateConfig(data: any) { +// 收藏 +export function star(data: any) { return request({ method: 'post', - url: 'updateConfig', + url: 'resource-favorites/star', data }); } -// 获取扩展数据 -export function getRuleExtras() { +// 取消收藏 +export function unstar(data: any) { return request({ - method: 'get', - url: 'getRuleExtras' + method: 'post', + url: 'resource-favorites/unstar', + data }); } -// 测速 -export function ping(data: any) { +// ====================================== +// =============== 规则 =============== +// ====================================== + +// 导入规则 +export function importCMS(data: any) { return request({ method: 'post', - url: 'ping', + url: 'resource-rule/import-cms', data }); } -// 批量更新规则 -export function batchUpdateRules(data: any) { +// 创建规则 +export function createRule(data: any) { return request({ method: 'post', - url: 'batchUpdateRules', + url: 'resource-rule/create', data }); } -// 删除规则 -export function delRules(data: any) { +// 更新规则 +export function updateRule(data: any) { return request({ method: 'post', - url: 'delRules', + url: 'resource-rule/save', data }); } -// 更新排序 -export function updateRuleSort(data: any) { +// 获取所有规则 +export function getRules() { return request({ method: 'post', - url: 'updateRuleSort', - data + url: 'resource-rule/list' }); } -// 导入规则 -export function importRules(data: any) { +// 根据ID获取规则 +export function getRuleById(id: string) { return request({ method: 'post', - url: 'importRules', - data + url: 'resource-rule/find-by-id', + data: { id } }); } -export function install(data: { password: string }) { +// 删除规则 +export function delRules(data: any) { return request({ method: 'post', - url: 'install', + url: 'resource-rule/remove-by-id', data }); } -export function login(data: { password: string }) { +// 导入规则 +export function importRules(data: any) { return request({ method: 'post', - url: 'login', + url: 'resource-rule/import', data }); } -export function logout() { +// 批量更新规则 +export function batchUpdateRules(data: any) { return request({ - method: 'get', - url: 'logout' + method: 'post', + url: 'resource-rule/batch-update', + data }); } // ====================================== -// =============== 历史 =============== +// =============== 解析 =============== // ====================================== -// 获取历史 -export function getHistory() { +// 发现页分类列表 +export function discoverMap(ruleId: string) { return request({ method: 'post', - url: 'resource-history/list' + url: 'rule-manager/discover-map', + data: { + ruleId + } }); } -// 删除历史 -export function removeHistory(data: { ruleId: string; url: string }) { +// 发现页分类下内容 +export function discover(data: any) { return request({ method: 'post', - url: 'resource-history/remove', + url: 'rule-manager/discover', data }); } -// 添加历史 -export function addHistory(data: any) { +// 根据规则ID搜索内容 +export function searchByRuleId(data: { ruleId: string; keyword: string }) { return request({ method: 'post', - url: 'resource-history/add', + url: 'rule-manager/search-by-rule-id', data }); } -// ====================================== -// =============== 收藏 =============== -// ====================================== +// 获取内容 +export function getContent(data: any) { + return request({ + method: 'post', + url: 'rule-manager/content', + data + }); +} -// 获取收藏列表 -export function getFavorites() { +// 获取章节 +export function getChapter(filePath: string, ruleId?: string) { return request({ method: 'post', - url: 'resource-favorites/list' + url: 'rule-manager/chapter', + data: { + filePath, + ruleId + } }); } -// 收藏 -export function star(data: any) { + +// ====================================== +// =============== 配置 =============== +// ====================================== + +// 获取配置 +export function readConfig() { return request({ method: 'post', - url: 'resource-favorites/star', - data + url: '/config/read' }); } -// 取消收藏 -export function unstar(data: any) { +// 更新配置 +export function updateConfig(data: any) { return request({ method: 'post', - url: 'resource-favorites/unstar', + url: '/config/save', data }); } // ====================================== -// =============== 规则 =============== +// =============== 书架 =============== // ====================================== -// 导入规则 -export function importCMS(data: any) { +// 获取本地 +export function getLocalBooks() { return request({ method: 'post', - url: 'resource-rule/import-cms', - data + url: 'bookshelf/list' }); } diff --git a/packages/web/src/pages/pc/rules/index.vue b/packages/web/src/pages/pc/rules/index.vue index 7b0466cd..61146111 100644 --- a/packages/web/src/pages/pc/rules/index.vue +++ b/packages/web/src/pages/pc/rules/index.vue @@ -118,6 +118,12 @@ const fileInputRef = ref(); ruleExtra.sync(); +onMounted(async () => { + loading.value = true; + await rulesStore.sync(); + loading.value = false; +}); + const searchText = ref(''); const contentTypes = ref(CONTENT_TYPES.map((e) => e.value).flat()); diff --git a/packages/web/src/router/router.pc.ts b/packages/web/src/router/router.pc.ts index e6675849..1208e5d9 100644 --- a/packages/web/src/router/router.pc.ts +++ b/packages/web/src/router/router.pc.ts @@ -66,10 +66,7 @@ const router = createRouter({ }, { path: 'rules', - component: () => import('@/pages/pc/rules/index.vue'), - meta: { - keepAlive: true - } + component: () => import('@/pages/pc/rules/index.vue') }, { path: 'chapter', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11bd3a98..18cb62c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,12 +24,18 @@ importers: bumpp: specifier: ^9.4.1 version: 9.4.1 + cross-env: + specifier: ^7.0.3 + version: 7.0.3 husky: specifier: ^8.0.0 version: 8.0.3 npm-run-all: specifier: ^4.1.5 version: 4.1.5 + tsx: + specifier: ^4.16.2 + version: 4.16.2 unbuild: specifier: ^2.0.0 version: 2.0.0(sass@1.77.8)(typescript@5.3.3)(vue-tsc@2.0.26(typescript@5.3.3)) @@ -38,7 +44,7 @@ importers: devDependencies: vitepress: specifier: ^1.3.0 - version: 1.3.0(@algolia/client-search@4.24.0)(@types/node@20.14.10)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.39)(sass@1.77.8)(search-insights@2.15.0)(terser@5.31.2)(typescript@5.3.3) + version: 1.3.0(@algolia/client-search@4.24.0)(@types/node@20.14.10)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.39)(react@18.3.1)(sass@1.77.8)(search-insights@2.15.0)(terser@5.31.2)(typescript@5.3.3) packages/cli: dependencies: @@ -104,9 +110,6 @@ importers: eslint: specifier: ^8.44.0 version: 8.57.0 - esno: - specifier: ^0.16.3 - version: 0.16.3 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@18.19.39) @@ -219,9 +222,6 @@ importers: '@types/koa__cors': specifier: ^5.0.0 version: 5.0.0 - esno: - specifier: ^0.16.3 - version: 0.16.3 packages/shared: dependencies: @@ -286,9 +286,6 @@ importers: '@types/node': specifier: ^18.16.19 version: 18.19.39 - esno: - specifier: ^0.16.3 - version: 0.16.3 reflect-metadata: specifier: ^0.2.2 version: 0.2.2 @@ -570,9 +567,6 @@ importers: chalk: specifier: ^5.2.0 version: 5.3.0 - cross-env: - specifier: ^7.0.3 - version: 7.0.3 electron: specifier: 30.0.6 version: 30.0.6 @@ -1043,12 +1037,6 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.19.12': resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} engines: {node: '>=12'} @@ -1061,12 +1049,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.19.12': resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} engines: {node: '>=12'} @@ -1079,12 +1061,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.19.12': resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} engines: {node: '>=12'} @@ -1097,12 +1073,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.19.12': resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} engines: {node: '>=12'} @@ -1115,12 +1085,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.19.12': resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} engines: {node: '>=12'} @@ -1133,12 +1097,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.19.12': resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} engines: {node: '>=12'} @@ -1151,12 +1109,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.19.12': resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} engines: {node: '>=12'} @@ -1169,12 +1121,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.19.12': resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} engines: {node: '>=12'} @@ -1187,12 +1133,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.19.12': resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} engines: {node: '>=12'} @@ -1205,12 +1145,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.19.12': resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} engines: {node: '>=12'} @@ -1223,12 +1157,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.19.12': resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} engines: {node: '>=12'} @@ -1241,12 +1169,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.19.12': resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} engines: {node: '>=12'} @@ -1259,12 +1181,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.19.12': resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} engines: {node: '>=12'} @@ -1277,12 +1193,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.19.12': resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} engines: {node: '>=12'} @@ -1295,12 +1205,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.19.12': resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} engines: {node: '>=12'} @@ -1313,12 +1217,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.19.12': resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} engines: {node: '>=12'} @@ -1331,12 +1229,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.19.12': resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} engines: {node: '>=12'} @@ -1349,12 +1241,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.19.12': resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} engines: {node: '>=12'} @@ -1367,12 +1253,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.19.12': resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} engines: {node: '>=12'} @@ -1385,12 +1265,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.19.12': resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} engines: {node: '>=12'} @@ -1403,12 +1277,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.19.12': resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} engines: {node: '>=12'} @@ -1421,12 +1289,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.19.12': resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} engines: {node: '>=12'} @@ -1466,6 +1328,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -1473,6 +1336,7 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -1746,46 +1610,55 @@ packages: resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.18.1': resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.18.1': resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.18.1': resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.18.1': resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.18.1': resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.18.1': resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.18.1': resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.18.1': resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} @@ -2694,10 +2567,12 @@ packages: are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} + deprecated: This package is no longer supported. are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -3658,11 +3533,6 @@ packages: es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.19.12: resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} engines: {node: '>=12'} @@ -3876,10 +3746,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true - esno@0.16.3: - resolution: {integrity: sha512-6slSBEV1lMKcX13DBifvnDFpNno5WXhw4j/ff7RI0y51BZiDqEe5dNhhjhIQ3iCOQuzsm2MbVzmwqbN78BBhPg==} - hasBin: true - espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4100,10 +3966,12 @@ packages: gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} + deprecated: This package is no longer supported. gauge@4.0.4: resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -4165,13 +4033,16 @@ packages: glob@7.1.2: resolution: {integrity: sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==} + deprecated: Glob versions prior to v9 are no longer supported glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported global-agent@3.0.0: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} @@ -4400,6 +4271,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -5417,10 +5289,12 @@ packages: npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. nprogress@0.2.0: resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} @@ -5948,6 +5822,7 @@ packages: puppeteer@21.11.0: resolution: {integrity: sha512-9jTHuYe22TD3sNxy0nEIzC7ZrlRnDgeX3xPkbS7PnbdwYjl2o/z/YuCrRBwezdKpbTDTJ4VqIggzNyeRcKq3cg==} engines: {node: '>=16.13.2'} + deprecated: < 22.6.4 is no longer supported hasBin: true pure-rand@6.1.0: @@ -6097,6 +5972,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true roarr@2.15.4: @@ -6705,8 +6581,9 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tsx@3.14.0: - resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} + tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} hasBin: true type-check@0.4.0: @@ -7813,9 +7690,9 @@ snapshots: '@docsearch/css@3.6.0': {} - '@docsearch/js@3.6.0(@algolia/client-search@4.24.0)(search-insights@2.15.0)': + '@docsearch/js@3.6.0(@algolia/client-search@4.24.0)(react@18.3.1)(search-insights@2.15.0)': dependencies: - '@docsearch/react': 3.6.0(@algolia/client-search@4.24.0)(search-insights@2.15.0) + '@docsearch/react': 3.6.0(@algolia/client-search@4.24.0)(react@18.3.1)(search-insights@2.15.0) preact: 10.22.1 transitivePeerDependencies: - '@algolia/client-search' @@ -7824,13 +7701,14 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.6.0(@algolia/client-search@4.24.0)(search-insights@2.15.0)': + '@docsearch/react@3.6.0(@algolia/client-search@4.24.0)(react@18.3.1)(search-insights@2.15.0)': dependencies: '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.15.0) '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) '@docsearch/css': 3.6.0 algoliasearch: 4.24.0 optionalDependencies: + react: 18.3.1 search-insights: 2.15.0 transitivePeerDependencies: - '@algolia/client-search' @@ -7896,198 +7774,132 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/android-arm64@0.18.20': - optional: true - '@esbuild/android-arm64@0.19.12': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm@0.18.20': - optional: true - '@esbuild/android-arm@0.19.12': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-x64@0.18.20': - optional: true - '@esbuild/android-x64@0.19.12': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.18.20': - optional: true - '@esbuild/darwin-arm64@0.19.12': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-x64@0.18.20': - optional: true - '@esbuild/darwin-x64@0.19.12': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.18.20': - optional: true - '@esbuild/freebsd-arm64@0.19.12': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.18.20': - optional: true - '@esbuild/freebsd-x64@0.19.12': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/linux-arm64@0.18.20': - optional: true - '@esbuild/linux-arm64@0.19.12': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm@0.18.20': - optional: true - '@esbuild/linux-arm@0.19.12': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-ia32@0.18.20': - optional: true - '@esbuild/linux-ia32@0.19.12': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-loong64@0.18.20': - optional: true - '@esbuild/linux-loong64@0.19.12': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-mips64el@0.18.20': - optional: true - '@esbuild/linux-mips64el@0.19.12': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-ppc64@0.18.20': - optional: true - '@esbuild/linux-ppc64@0.19.12': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.18.20': - optional: true - '@esbuild/linux-riscv64@0.19.12': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-s390x@0.18.20': - optional: true - '@esbuild/linux-s390x@0.19.12': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-x64@0.18.20': - optional: true - '@esbuild/linux-x64@0.19.12': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.18.20': - optional: true - '@esbuild/netbsd-x64@0.19.12': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.18.20': - optional: true - '@esbuild/openbsd-x64@0.19.12': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.18.20': - optional: true - '@esbuild/sunos-x64@0.19.12': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/win32-arm64@0.18.20': - optional: true - '@esbuild/win32-arm64@0.19.12': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-ia32@0.18.20': - optional: true - '@esbuild/win32-ia32@0.19.12': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-x64@0.18.20': - optional: true - '@esbuild/win32-x64@0.19.12': optional: true @@ -10989,31 +10801,6 @@ snapshots: es6-error@4.1.1: optional: true - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - esbuild@0.19.12: optionalDependencies: '@esbuild/aix-ppc64': 0.19.12 @@ -11332,10 +11119,6 @@ snapshots: transitivePeerDependencies: - supports-color - esno@0.16.3: - dependencies: - tsx: 3.14.0 - espree@9.6.1: dependencies: acorn: 8.12.1 @@ -11632,7 +11415,7 @@ snapshots: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.3.4 + debug: 4.3.5(supports-color@8.1.1) fs-extra: 11.2.0 transitivePeerDependencies: - supports-color @@ -13337,7 +13120,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.5(supports-color@8.1.1) get-uri: 6.0.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 @@ -14139,7 +13922,7 @@ snapshots: socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.5(supports-color@8.1.1) socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -14541,11 +14324,10 @@ snapshots: tslib: 1.14.1 typescript: 5.3.3 - tsx@3.14.0: + tsx@4.16.2: dependencies: - esbuild: 0.18.20 + esbuild: 0.21.5 get-tsconfig: 4.7.5 - source-map-support: 0.5.21 optionalDependencies: fsevents: 2.3.3 @@ -14899,10 +14681,10 @@ snapshots: sass: 1.77.8 terser: 5.31.2 - vitepress@1.3.0(@algolia/client-search@4.24.0)(@types/node@20.14.10)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.39)(sass@1.77.8)(search-insights@2.15.0)(terser@5.31.2)(typescript@5.3.3): + vitepress@1.3.0(@algolia/client-search@4.24.0)(@types/node@20.14.10)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.39)(react@18.3.1)(sass@1.77.8)(search-insights@2.15.0)(terser@5.31.2)(typescript@5.3.3): dependencies: '@docsearch/css': 3.6.0 - '@docsearch/js': 3.6.0(@algolia/client-search@4.24.0)(search-insights@2.15.0) + '@docsearch/js': 3.6.0(@algolia/client-search@4.24.0)(react@18.3.1)(search-insights@2.15.0) '@shikijs/core': 1.10.3 '@shikijs/transformers': 1.10.3 '@types/markdown-it': 14.1.1